Check-in [6f04d73ab2]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:implementing version 2.0 - XLSX and ODS support
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6f04d73ab288159695f942552faee8dd63fba689995db1f1143ca4805adfcb01
User & Date: sandro 2021-06-12 08:49:36
Context
2021-06-12
14:38
releasing 2.0.0-RC0 check-in: c571d874ad user: sandro tags: trunk
08:49
implementing version 2.0 - XLSX and ODS support check-in: 6f04d73ab2 user: sandro tags: trunk
2021-01-19
09:38
switching to automake 1.16.2 check-in: 18deb62019 user: sandro tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to config-msvc.h.

7
8
9
10
11
12
13



14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29
30
..
72
73
74
75
76
77
78



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the <iconv.h> header file. */
#define HAVE_ICONV_H 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1




/* Define to 1 if `lstat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */

/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1




/* Define to 1 if you have the `sqrt' function. */
/* #undef HAVE_SQRT */

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
................................................................................
   slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"




/* Name of package */
#define PACKAGE "freexl"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 1.0.6"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.6"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "1.0.6"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */







>
>
>










>
>
>







 







>
>
>










|








|











|













7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the <iconv.h> header file. */
#define HAVE_ICONV_H 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the `expat' library (-lexpat). */
/* #undef HAVE_LIBEXPAT */

/* Define to 1 if `lstat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */

/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the <minizip/unzip.h> header file. */
/* #undef HAVE_MINIZIP_UNZIP_H */

/* Define to 1 if you have the `sqrt' function. */
/* #undef HAVE_SQRT */

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
................................................................................
   slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"

/* Should be defined in order to disable XML documents support. */
/* #undef OMIT_XMLDOC */

/* Name of package */
#define PACKAGE "freexl"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 2.0.0"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "2.0.0"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "2.0.0"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */

Changes to config.h.

1
2
3
4
5



6
7
8
9
10
11



12
13
14
15
16
17
18
19
20
21



22
23
24
25
26
27
28
..
70
71
72
73
74
75
76



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1




/* Define to 1 if you have the <iconv.h> header file. */
#define HAVE_ICONV_H 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1




/* Define to 1 if `lstat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */

/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1




/* Define to 1 if you have the `sqrt' function. */
/* #undef HAVE_SQRT */

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
................................................................................
   slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"




/* Name of package */
#define PACKAGE "freexl"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 1.0.6"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.6"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "1.0.6"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */





>
>
>






>
>
>










>
>
>







 







>
>
>










|








|











|













1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the <expat.h> header file. */
#define HAVE_EXPAT_H 1

/* Define to 1 if you have the <iconv.h> header file. */
#define HAVE_ICONV_H 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the `expat' library (-lexpat). */
#define HAVE_LIBEXPAT 1

/* Define to 1 if `lstat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */

/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the <minizip/unzip.h> header file. */
#define HAVE_MINIZIP_UNZIP_H 1

/* Define to 1 if you have the `sqrt' function. */
/* #undef HAVE_SQRT */

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
................................................................................
   slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"

/* Should be defined in order to disable XML documents support. */
/* #undef OMIT_XMLDOC */

/* Name of package */
#define PACKAGE "freexl"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 2.0.0-devel"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "2.0.0-devel"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "2.0.0-devel"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */

Changes to config.h.in.

1
2
3
4



5
6
7
8
9
10



11
12
13
14
15
16
17
18
19
20



21
22
23
24
25
26
27
..
68
69
70
71
72
73
74



75
76
77
78
79
80
81
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H




/* Define to 1 if you have the <iconv.h> header file. */
#undef HAVE_ICONV_H

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H




/* Define to 1 if `lstat' has the bug that it succeeds when given the
   zero-length file name argument. */
#undef HAVE_LSTAT_EMPTY_STRING_BUG

/* Define to 1 if you have the <math.h> header file. */
#undef HAVE_MATH_H

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H




/* Define to 1 if you have the `sqrt' function. */
#undef HAVE_SQRT

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
................................................................................
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
   slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#undef LT_OBJDIR




/* Name of package */
#undef PACKAGE

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT





>
>
>






>
>
>










>
>
>







 







>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H

/* Define to 1 if you have the <expat.h> header file. */
#undef HAVE_EXPAT_H

/* Define to 1 if you have the <iconv.h> header file. */
#undef HAVE_ICONV_H

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define to 1 if you have the `expat' library (-lexpat). */
#undef HAVE_LIBEXPAT

/* Define to 1 if `lstat' has the bug that it succeeds when given the
   zero-length file name argument. */
#undef HAVE_LSTAT_EMPTY_STRING_BUG

/* Define to 1 if you have the <math.h> header file. */
#undef HAVE_MATH_H

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H

/* Define to 1 if you have the <minizip/unzip.h> header file. */
#undef HAVE_MINIZIP_UNZIP_H

/* Define to 1 if you have the `sqrt' function. */
#undef HAVE_SQRT

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
................................................................................
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
   slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#undef LT_OBJDIR

/* Should be defined in order to disable XML documents support. */
#undef OMIT_XMLDOC

/* Name of package */
#undef PACKAGE

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

Changes to configure.

1
2
3
4
5
6
7
8
9
10
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
...
768
769
770
771
772
773
774

775
776
777
778
779
780
781
....
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
....
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
....
1415
1416
1417
1418
1419
1420
1421

1422
1423
1424
1425
1426
1427
1428
....
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
....
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
....
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
....
3037
3038
3039
3040
3041
3042
3043



3044
3045
3046
3047
3048
3049
3050
.....
17268
17269
17270
17271
17272
17273
17274























































































































































17275
17276
17277
17278
17279
17280
17281
.....
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
.....
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for FreeXL 1.0.6.
#
# Report bugs to <a.furieri@lqt.it>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
................................................................................
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='FreeXL'
PACKAGE_TARNAME='freexl'
PACKAGE_VERSION='1.0.6'
PACKAGE_STRING='FreeXL 1.0.6'
PACKAGE_BUGREPORT='a.furieri@lqt.it'
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
................................................................................
enable_static
with_pic
enable_fast_install
with_gnu_ld
with_sysroot
enable_libtool_lock
enable_gcov

'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS
................................................................................
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures FreeXL 1.0.6 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
................................................................................
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of FreeXL 1.0.6:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
                          speeds up one-time build
  --enable-shared[=PKGS]  build shared libraries [default=yes]
  --enable-static[=PKGS]  build static libraries [default=yes]
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)
  --enable-gcov           turn on code coverage analysis tools


Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-pic              try to use only PIC/non-PIC objects [default=use
                          both]
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
................................................................................
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
FreeXL configure 1.0.6
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
................................................................................
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_type
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by FreeXL $as_me 1.0.6, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
................................................................................
    CYGPATH_W=echo
  fi
fi


# Define the identity of the package.
 PACKAGE='freexl'
 VERSION='1.0.6'


cat >>confdefs.h <<_ACEOF
#define PACKAGE "$PACKAGE"
_ACEOF


................................................................................
fi

  MAINT=$MAINTAINER_MODE_TRUE


ac_config_headers="$ac_config_headers config.h"






# Checks for header files.
DEPDIR="${am__leading_dot}deps"

ac_config_commands="$ac_config_commands depfiles"

................................................................................
else
  as_fn_error $? "'libcharset' is required but it doesn't seem to be installed on this system." "$LINENO" 5
fi

fi

























































































































































cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
................................................................................
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by FreeXL $as_me 1.0.6, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
................................................................................

Report bugs to <a.furieri@lqt.it>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
FreeXL config.status 1.0.6
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."



|







 







|
|







 







>







 







|







 







|







 







>







 







|







 







|







 







|







 







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







1
2
3
4
5
6
7
8
9
10
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
...
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
....
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
....
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
....
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
....
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
....
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
....
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
....
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
.....
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
.....
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
.....
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for FreeXL 2.0.0-devel.
#
# Report bugs to <a.furieri@lqt.it>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
................................................................................
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='FreeXL'
PACKAGE_TARNAME='freexl'
PACKAGE_VERSION='2.0.0-devel'
PACKAGE_STRING='FreeXL 2.0.0-devel'
PACKAGE_BUGREPORT='a.furieri@lqt.it'
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
................................................................................
enable_static
with_pic
enable_fast_install
with_gnu_ld
with_sysroot
enable_libtool_lock
enable_gcov
enable_xmldocs
'
      ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS
................................................................................
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures FreeXL 2.0.0-devel to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
................................................................................
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of FreeXL 2.0.0-devel:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
                          speeds up one-time build
  --enable-shared[=PKGS]  build shared libraries [default=yes]
  --enable-static[=PKGS]  build static libraries [default=yes]
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)
  --enable-gcov           turn on code coverage analysis tools
  --enable-xmldocs        enables XML documents support [default=yes]

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-pic              try to use only PIC/non-PIC objects [default=use
                          both]
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
................................................................................
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
FreeXL configure 2.0.0-devel
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
................................................................................
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_type
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by FreeXL $as_me 2.0.0-devel, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
................................................................................
    CYGPATH_W=echo
  fi
fi


# Define the identity of the package.
 PACKAGE='freexl'
 VERSION='2.0.0-devel'


cat >>confdefs.h <<_ACEOF
#define PACKAGE "$PACKAGE"
_ACEOF


................................................................................
fi

  MAINT=$MAINTAINER_MODE_TRUE


ac_config_headers="$ac_config_headers config.h"


# config depending options



# Checks for header files.
DEPDIR="${am__leading_dot}deps"

ac_config_commands="$ac_config_commands depfiles"

................................................................................
else
  as_fn_error $? "'libcharset' is required but it doesn't seem to be installed on this system." "$LINENO" 5
fi

fi


#-----------------------------------------------------------------------
#   --enable-xmldocs
#
# Check whether --enable-xmldocs was given.
if test "${enable_xmldocs+set}" = set; then :
  enableval=$enable_xmldocs;
else
  enable_xmldocs=yes
fi

if test x"$enable_xmldocs" != "xyes"; then
  $as_echo "#define OMIT_XMLDOC 1" >>confdefs.h

else
for ac_header in minizip/unzip.h
do :
  ac_fn_c_check_header_mongrel "$LINENO" "minizip/unzip.h" "ac_cv_header_minizip_unzip_h" "$ac_includes_default"
if test "x$ac_cv_header_minizip_unzip_h" = xyes; then :
  cat >>confdefs.h <<_ACEOF
#define HAVE_MINIZIP_UNZIP_H 1
_ACEOF

else
  as_fn_error $? "cannot find minizip/unzip.h, bailing out" "$LINENO" 5
fi

done

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing unzLocateFile" >&5
$as_echo_n "checking for library containing unzLocateFile... " >&6; }
if ${ac_cv_search_unzLocateFile+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char unzLocateFile ();
int
main ()
{
return unzLocateFile ();
  ;
  return 0;
}
_ACEOF
for ac_lib in '' minizip; do
  if test -z "$ac_lib"; then
    ac_res="none required"
  else
    ac_res=-l$ac_lib
    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
  fi
  if ac_fn_c_try_link "$LINENO"; then :
  ac_cv_search_unzLocateFile=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext
  if ${ac_cv_search_unzLocateFile+:} false; then :
  break
fi
done
if ${ac_cv_search_unzLocateFile+:} false; then :

else
  ac_cv_search_unzLocateFile=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_unzLocateFile" >&5
$as_echo "$ac_cv_search_unzLocateFile" >&6; }
ac_res=$ac_cv_search_unzLocateFile
if test "$ac_res" != no; then :
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

else
  as_fn_error $? "'libminizip' is required but it doesn't seem to be installed on this system." "$LINENO" 5
fi


for ac_header in expat.h
do :
  ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default"
if test "x$ac_cv_header_expat_h" = xyes; then :
  cat >>confdefs.h <<_ACEOF
#define HAVE_EXPAT_H 1
_ACEOF

else
  as_fn_error $? "cannot find expat.h, bailing out" "$LINENO" 5
fi

done

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_ParserCreate in -lexpat" >&5
$as_echo_n "checking for XML_ParserCreate in -lexpat... " >&6; }
if ${ac_cv_lib_expat_XML_ParserCreate+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lexpat  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char XML_ParserCreate ();
int
main ()
{
return XML_ParserCreate ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
  ac_cv_lib_expat_XML_ParserCreate=yes
else
  ac_cv_lib_expat_XML_ParserCreate=no
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_ParserCreate" >&5
$as_echo "$ac_cv_lib_expat_XML_ParserCreate" >&6; }
if test "x$ac_cv_lib_expat_XML_ParserCreate" = xyes; then :
  cat >>confdefs.h <<_ACEOF
#define HAVE_LIBEXPAT 1
_ACEOF

  LIBS="-lexpat $LIBS"

else
  as_fn_error $? "'expat' is required but it doesn't seem to be installed on this system." "$LINENO" 5
fi

fi
#-----------------------------------------------------------------------

cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#
................................................................................
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by FreeXL $as_me 2.0.0-devel, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
................................................................................

Report bugs to <a.furieri@lqt.it>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
FreeXL config.status 2.0.0-devel
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

Changes to configure.ac.

1
2
3
4
5
6
7
8
9
10
11
12
13




14
15
16
17
18
19
20
..
64
65
66
67
68
69
70
71

















72
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.61)
AC_INIT(FreeXL, 1.0.6, a.furieri@lqt.it)
AC_LANG(C)
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])

AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AM_CONFIG_HEADER(config.h)






# Checks for header files.
AC_CHECK_HEADERS(stdlib.h,, [AC_MSG_ERROR([cannot find stdlib.h, bailing out])])
AC_CHECK_HEADERS(stdio.h,, [AC_MSG_ERROR([cannot find stdio.h, bailing out])])
AC_CHECK_HEADERS(string.h,, [AC_MSG_ERROR([cannot find string.h, bailing out])])
AC_CHECK_HEADERS(math.h,, [AC_MSG_ERROR([cannot find math.h, bailing out])])

................................................................................
AC_CHECK_HEADERS(iconv.h,, [AC_MSG_ERROR([cannot find iconv.h, bailing out])])
# on some systems "iconv()" lives in libc. On others it lives in libiconv
#  on older systems "libiconv()" lives in libiconv
AC_SEARCH_LIBS(iconv,iconv,,
	AC_SEARCH_LIBS(libiconv,iconv,,AC_MSG_ERROR(['libiconv' is required but it doesn't seem to be installed on this system.]),))
AC_SEARCH_LIBS(locale_charset,charset,,
	AC_SEARCH_LIBS(nl_langinfo,c,,AC_MSG_ERROR(['libcharset' is required but it doesn't seem to be installed on this system.]),))


















AC_OUTPUT




|








>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.61)
AC_INIT(FreeXL, 2.0.0-devel, a.furieri@lqt.it)
AC_LANG(C)
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])

AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AM_CONFIG_HEADER(config.h)

# config depending options
AH_TEMPLATE([OMIT_XMLDOC],
            [Should be defined in order to disable XML documents support.])


# Checks for header files.
AC_CHECK_HEADERS(stdlib.h,, [AC_MSG_ERROR([cannot find stdlib.h, bailing out])])
AC_CHECK_HEADERS(stdio.h,, [AC_MSG_ERROR([cannot find stdio.h, bailing out])])
AC_CHECK_HEADERS(string.h,, [AC_MSG_ERROR([cannot find string.h, bailing out])])
AC_CHECK_HEADERS(math.h,, [AC_MSG_ERROR([cannot find math.h, bailing out])])

................................................................................
AC_CHECK_HEADERS(iconv.h,, [AC_MSG_ERROR([cannot find iconv.h, bailing out])])
# on some systems "iconv()" lives in libc. On others it lives in libiconv
#  on older systems "libiconv()" lives in libiconv
AC_SEARCH_LIBS(iconv,iconv,,
	AC_SEARCH_LIBS(libiconv,iconv,,AC_MSG_ERROR(['libiconv' is required but it doesn't seem to be installed on this system.]),))
AC_SEARCH_LIBS(locale_charset,charset,,
	AC_SEARCH_LIBS(nl_langinfo,c,,AC_MSG_ERROR(['libcharset' is required but it doesn't seem to be installed on this system.]),))

#-----------------------------------------------------------------------
#   --enable-xmldocs
#
AC_ARG_ENABLE(xmldocs, [AS_HELP_STRING(
  [--enable-xmldocs], [enables XML documents support [default=yes]])],
  [], [enable_xmldocs=yes])
if test x"$enable_xmldocs" != "xyes"; then
  AC_DEFINE(OMIT_XMLDOC)
else
AC_CHECK_HEADERS(minizip/unzip.h,, [AC_MSG_ERROR([cannot find minizip/unzip.h, bailing out])])
AC_SEARCH_LIBS(unzLocateFile, minizip,,AC_MSG_ERROR(['libminizip' is required but it doesn't seem to be installed on this system.]))

AC_CHECK_HEADERS(expat.h,, [AC_MSG_ERROR([cannot find expat.h, bailing out])])
AC_CHECK_LIB(expat,XML_ParserCreate,,AC_MSG_ERROR(['expat' is required but it doesn't seem to be installed on this system.]))
fi
#-----------------------------------------------------------------------

AC_OUTPUT

Changes to examples/Makefile.am.

1
2
3
4
5
6
7
8
noinst_PROGRAMS = test_xl xl2sql

AM_CFLAGS = -I@srcdir@/../headers
AM_LDFLAGS = -L../src -lfreexl -lm $(GCOV_FLAGS)

MOSTLYCLEANFILES = *.gcna *.gcno *.gcda

EXTRA_DIST = examples.doxy
|







1
2
3
4
5
6
7
8
noinst_PROGRAMS = test_xl test_xlsx test_ods xl2sql xlsx2sql ods2sql

AM_CFLAGS = -I@srcdir@/../headers
AM_LDFLAGS = -L../src -lfreexl -lm $(GCOV_FLAGS)

MOSTLYCLEANFILES = *.gcna *.gcno *.gcda

EXTRA_DIST = examples.doxy

Changes to examples/Makefile.in.

84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112









113
114
115



116
117
118
119
120
121
122
...
124
125
126
127
128
129
130

131

132
133
134
135
136
137
138
...
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
...
339
340
341
342
343
344
345








346
347
348
349




350
351
352
353




354
355
356
357
358
359
360


361

362

363
364
365
366
367
368
369
...
516
517
518
519
520
521
522


523

524

525
526
527
528
529
530
531
...
563
564
565
566
567
568
569


570

571

572
573
574
575
576
577
578
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = test_xl$(EXEEXT) xl2sql$(EXEEXT)


subdir = examples
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
................................................................................
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
test_xl_SOURCES = test_xl.c
test_xl_OBJECTS = test_xl.$(OBJEXT)
test_xl_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 









xl2sql_SOURCES = xl2sql.c
xl2sql_OBJECTS = xl2sql.$(OBJEXT)
xl2sql_LDADD = $(LDADD)



AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
................................................................................
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles

am__depfiles_remade = ./$(DEPDIR)/test_xl.Po ./$(DEPDIR)/xl2sql.Po

am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
................................................................................
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = test_xl.c xl2sql.c
DIST_SOURCES = test_xl.c xl2sql.c


am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
................................................................................
	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list









test_xl$(EXEEXT): $(test_xl_OBJECTS) $(test_xl_DEPENDENCIES) $(EXTRA_test_xl_DEPENDENCIES) 
	@rm -f test_xl$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_xl_OBJECTS) $(test_xl_LDADD) $(LIBS)





xl2sql$(EXEEXT): $(xl2sql_OBJECTS) $(xl2sql_DEPENDENCIES) $(EXTRA_xl2sql_DEPENDENCIES) 
	@rm -f xl2sql$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(xl2sql_OBJECTS) $(xl2sql_LDADD) $(LIBS)





mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c



@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_xl.Po@am__quote@ # am--include-marker

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xl2sql.Po@am__quote@ # am--include-marker


$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

................................................................................
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
	mostlyclean-am

distclean: distclean-am


		-rm -f ./$(DEPDIR)/test_xl.Po

	-rm -f ./$(DEPDIR)/xl2sql.Po

	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:
................................................................................
install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am


		-rm -f ./$(DEPDIR)/test_xl.Po

	-rm -f ./$(DEPDIR)/xl2sql.Po

	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool







|
>
>







 







|
|
|




>
>
>
>
>
>
>
>
>



>
>
>







 







>
|
>







 







|
|
>
>







 







>
>
>
>
>
>
>
>




>
>
>
>




>
>
>
>







>
>

>

>







 







>
>
|
>

>







 







>
>
|
>

>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = test_xl$(EXEEXT) test_xlsx$(EXEEXT) \
	test_ods$(EXEEXT) xl2sql$(EXEEXT) xlsx2sql$(EXEEXT) \
	ods2sql$(EXEEXT)
subdir = examples
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
................................................................................
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
ods2sql_SOURCES = ods2sql.c
ods2sql_OBJECTS = ods2sql.$(OBJEXT)
ods2sql_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 
test_ods_SOURCES = test_ods.c
test_ods_OBJECTS = test_ods.$(OBJEXT)
test_ods_LDADD = $(LDADD)
test_xl_SOURCES = test_xl.c
test_xl_OBJECTS = test_xl.$(OBJEXT)
test_xl_LDADD = $(LDADD)
test_xlsx_SOURCES = test_xlsx.c
test_xlsx_OBJECTS = test_xlsx.$(OBJEXT)
test_xlsx_LDADD = $(LDADD)
xl2sql_SOURCES = xl2sql.c
xl2sql_OBJECTS = xl2sql.$(OBJEXT)
xl2sql_LDADD = $(LDADD)
xlsx2sql_SOURCES = xlsx2sql.c
xlsx2sql_OBJECTS = xlsx2sql.$(OBJEXT)
xlsx2sql_LDADD = $(LDADD)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
................................................................................
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/ods2sql.Po ./$(DEPDIR)/test_ods.Po \
	./$(DEPDIR)/test_xl.Po ./$(DEPDIR)/test_xlsx.Po \
	./$(DEPDIR)/xl2sql.Po ./$(DEPDIR)/xlsx2sql.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
................................................................................
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = ods2sql.c test_ods.c test_xl.c test_xlsx.c xl2sql.c \
	xlsx2sql.c
DIST_SOURCES = ods2sql.c test_ods.c test_xl.c test_xlsx.c xl2sql.c \
	xlsx2sql.c
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
................................................................................
	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

ods2sql$(EXEEXT): $(ods2sql_OBJECTS) $(ods2sql_DEPENDENCIES) $(EXTRA_ods2sql_DEPENDENCIES) 
	@rm -f ods2sql$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(ods2sql_OBJECTS) $(ods2sql_LDADD) $(LIBS)

test_ods$(EXEEXT): $(test_ods_OBJECTS) $(test_ods_DEPENDENCIES) $(EXTRA_test_ods_DEPENDENCIES) 
	@rm -f test_ods$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_ods_OBJECTS) $(test_ods_LDADD) $(LIBS)

test_xl$(EXEEXT): $(test_xl_OBJECTS) $(test_xl_DEPENDENCIES) $(EXTRA_test_xl_DEPENDENCIES) 
	@rm -f test_xl$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_xl_OBJECTS) $(test_xl_LDADD) $(LIBS)

test_xlsx$(EXEEXT): $(test_xlsx_OBJECTS) $(test_xlsx_DEPENDENCIES) $(EXTRA_test_xlsx_DEPENDENCIES) 
	@rm -f test_xlsx$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_xlsx_OBJECTS) $(test_xlsx_LDADD) $(LIBS)

xl2sql$(EXEEXT): $(xl2sql_OBJECTS) $(xl2sql_DEPENDENCIES) $(EXTRA_xl2sql_DEPENDENCIES) 
	@rm -f xl2sql$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(xl2sql_OBJECTS) $(xl2sql_LDADD) $(LIBS)

xlsx2sql$(EXEEXT): $(xlsx2sql_OBJECTS) $(xlsx2sql_DEPENDENCIES) $(EXTRA_xlsx2sql_DEPENDENCIES) 
	@rm -f xlsx2sql$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(xlsx2sql_OBJECTS) $(xlsx2sql_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ods2sql.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ods.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_xl.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_xlsx.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xl2sql.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx2sql.Po@am__quote@ # am--include-marker

$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

................................................................................
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
	mostlyclean-am

distclean: distclean-am
		-rm -f ./$(DEPDIR)/ods2sql.Po
	-rm -f ./$(DEPDIR)/test_ods.Po
	-rm -f ./$(DEPDIR)/test_xl.Po
	-rm -f ./$(DEPDIR)/test_xlsx.Po
	-rm -f ./$(DEPDIR)/xl2sql.Po
	-rm -f ./$(DEPDIR)/xlsx2sql.Po
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:
................................................................................
install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f ./$(DEPDIR)/ods2sql.Po
	-rm -f ./$(DEPDIR)/test_ods.Po
	-rm -f ./$(DEPDIR)/test_xl.Po
	-rm -f ./$(DEPDIR)/test_xlsx.Po
	-rm -f ./$(DEPDIR)/xl2sql.Po
	-rm -f ./$(DEPDIR)/xlsx2sql.Po
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

Added examples/ods2sql.c.























































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/* 
/ ods2sql.c
/
/ FreeXL Sample code
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "freexl.h"

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

#ifndef OMIT_XMLDOC		/* only if XML support is enabled */

static void
make_table_name (const char *prefix, unsigned short index, char *table_name)
{
/* generating an SQL clean table name */
    char buf[2048];
    char *in = buf;
    char *out = table_name;
    sprintf (buf, "%s_%02u", prefix, index);

/* masking for SQL */
    *out++ = '"';
    while (*in != '\0')
      {
	  if (*in == '"')
	      *out++ = '"';
	  *out++ = *in++;
      }
    *out++ = '"';
    *out = '\0';
}

static void
print_sql_string (const char *string)
{
/* printing a well formatted SQL string */
    const char *p = string;
    putchar (',');
    putchar (' ');
    putchar ('\'');
    while (*p != '\0')
      {
	  if (*p == '\'')
	    {
		/* masking any ' as '' */
		putchar ('\'');
	    }
	  putchar (*p);
	  p++;
      }
    putchar ('\'');
}

#endif /* end conditional XML support */

int
main (int argc, char *argv[])
{
#ifdef OMIT_XMLDOC		/* XML support is not enabled */
    fprintf (stderr,
	     "Sorry, this version of ods2sql was built by disabling support XML documents\n");
    return -1;
#else
    unsigned int worksheet_index;
    const char *table_prefix = "ods_table";
    char table_name[2048];
    const void *handle;
    int ret;
    unsigned int max_worksheet;
    unsigned int rows;
    unsigned short columns;
    unsigned int row;
    unsigned short col;

    if (argc == 2 || argc == 3)
      {
	  if (argc == 3)
	      table_prefix = argv[2];
      }
    else
      {
	  fprintf (stderr, "usage: ods2sql path.ods [table_prefix]\n");
	  return -1;
      }

/* opening the .XLSX file [Workbook] */
    ret = freexl_open_xlsx (argv[1], &handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "OPEN ERROR: %d\n", ret);
	  return -1;
      }

/* querying XLSX Worksheet entries */
    ret = freexl_get_worksheets_count (handle, &max_worksheet);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "GET-WORKSHEETS-COUNT Error: %d\n", ret);
	  goto stop;
      }

/* SQL output */
    printf ("--\n-- this SQL script was automatically created by xlsx2sql\n");
    printf ("--\n-- input .xls document was: %s\n--\n", argv[1]);
    printf ("\nBEGIN;\n\n");

    for (worksheet_index = 0; worksheet_index < max_worksheet;
	 worksheet_index++)
      {
	  const char *worsheet_name;
	  make_table_name (table_prefix, worksheet_index, table_name);
	  ret =
	      freexl_get_worksheet_name (handle, worksheet_index,
					 &worsheet_name);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-WORKSHEET-NAME Error: %d\n", ret);
		goto stop;
	    }
	  /* selecting the active Worksheet */
	  ret = freexl_select_active_worksheet (handle, worksheet_index);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "SELECT-ACTIVE_WORKSHEET Error: %d\n", ret);
		goto stop;
	    }
	  /* dimensions */
	  ret = freexl_worksheet_dimensions (handle, &rows, &columns);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "WORKSHEET-DIMENSIONS Error: %d\n", ret);
		goto stop;
	    }

	  printf ("--\n-- creating a DB table\n");
	  printf ("-- extracting data from Worksheet #%u: %s\n--\n",
		  worksheet_index, worsheet_name);
	  printf ("CREATE TABLE %s (\n", table_name);
	  printf ("\trow_no INTEGER NOT NULL PRIMARY KEY");
	  for (col = 0; col < columns; col++)
	      printf (",\n\tcol_%03u MULTITYPE", col);
	  printf (");\n");

	  printf ("--\n-- populating the same table\n--\n");
	  for (row = 0; row < rows; row++)
	    {
		/* INSERT INTO statements */
		FreeXL_CellValue cell;

		printf ("INSERT INTO %s (row_no", table_name);
		for (col = 0; col < columns; col++)
		    printf (", col_%03u", col);
		printf (") VALUES (%u", row);
		for (col = 0; col < columns; col++)
		  {
		      ret = freexl_get_cell_value (handle, row, col, &cell);
		      if (ret != FREEXL_OK)
			{
			    fprintf (stderr,
				     "CELL-VALUE-ERROR (r=%u c=%u): %d\n", row,
				     col, ret);
			    goto stop;
			}
		      switch (cell.type)
			{
			case FREEXL_CELL_INT:
			    printf (", %d", cell.value.int_value);
			    break;
			case FREEXL_CELL_DOUBLE:
			    printf (", %1.12f", cell.value.double_value);
			    break;
			case FREEXL_CELL_TEXT:
			case FREEXL_CELL_SST_TEXT:
			    print_sql_string (cell.value.text_value);
			    break;
			case FREEXL_CELL_DATE:
			case FREEXL_CELL_DATETIME:
			case FREEXL_CELL_TIME:
			    printf (", '%s'", cell.value.text_value);
			    break;
			case FREEXL_CELL_NULL:
			default:
			    printf (", NULL");
			    break;
			};
		  }
		printf (");\n");
	    }
	  printf ("\n-- done: table end\n\n\n\n");
      }
    printf ("COMMIT;\n");

  stop:
/* closing the .XLSX file [Workbook] */
    ret = freexl_close (handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "CLOSE ERROR: %d\n", ret);
	  return -1;
      }

    return 0;
#endif /* end conditional XML support */
}

Added examples/test_ods.c.









































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* 
/ test_ods.c
/
/ FreeXL Sample code
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "freexl.h"

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

int
main (int argc, char *argv[])
{
#ifdef OMIT_XMLDOC		/* XML support is not enabled */
    fprintf (stderr,
	     "Sorry, this version of test_ods was built by disabling support XML documents\n");
    return -1;
#else
    const void *handle;
    int ret;
    unsigned int worksheet_count;
    unsigned int idx;
    const char *string;

    if (argc != 2)
      {
	  fprintf (stderr, "usage: test_ods path.ods\n");
	  return -1;
      }

/* opening the .ODS file [Workbook] */
    ret = freexl_open_ods (argv[1], &handle);
    if (ret != FREEXL_OK)
      {
	  freexl_close_ods (handle);
	  fprintf (stderr, "OPEN ERROR: %d\n", ret);
	  return -1;
      }

/* ODS Worksheet entries */
    ret = freexl_get_worksheets_count (handle, &worksheet_count);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "GET-WORKSHEETS-COUNT Error: %d\n", ret);
	  goto stop;
      }

    printf
	("\nWorksheets:\n=========================================================\n");
    for (idx = 0; idx < worksheet_count; idx++)
      {
	  /* printing XLSX Worksheets entries */
	  unsigned short active;
	  unsigned int rows;
	  unsigned short columns;

	  ret = freexl_get_worksheet_name (handle, idx, &string);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-WORKSHEET-NAME Error: %d\n", ret);
		goto stop;
	    }
	  if (string == NULL)
	      printf ("%3u] NULL (unnamed)\n", idx);
	  else
	      printf ("%3u] %s\n", idx, string);
	  ret = freexl_select_active_worksheet (handle, idx);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "SELECT-ACTIVE_WORKSHEET Error: %d\n", ret);
		goto stop;
	    }
	  ret = freexl_get_active_worksheet (handle, &active);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-ACTIVE_WORKSHEET Error: %d\n", ret);
		goto stop;
	    }
	  printf
	      ("\tok, Worksheet successfully selected: currently active: %u\n",
	       active);
	  ret = freexl_worksheet_dimensions (handle, &rows, &columns);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "WORKSHEET-DIMENSIONS Error: %d\n", ret);
		goto stop;
	    }
	  printf ("\t%u Rows X %u Columns\n\n", rows, columns);
      }

  stop:
/* closing the .ODS file [Workbook] */
    ret = freexl_close (handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "CLOSE ERROR: %d\n", ret);
	  return -1;
      }

    return 0;
#endif /* end conditional XML support */
}

Changes to examples/test_xl.c.

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
	    {
		if (strcmp (argv[2], "-verbose") == 0)
		    verbose = 1;
	    }
      }
    else
      {
	  fprintf (stderr, "usage: text_xl path.xls [-verbose]\n");
	  return -1;
      }

/* opening the .XLS file [Workbook] */
    ret = freexl_open (argv[1], &handle);
    if (ret != FREEXL_OK)
      {







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
	    {
		if (strcmp (argv[2], "-verbose") == 0)
		    verbose = 1;
	    }
      }
    else
      {
	  fprintf (stderr, "usage: test_xl path.xls [-verbose]\n");
	  return -1;
      }

/* opening the .XLS file [Workbook] */
    ret = freexl_open (argv[1], &handle);
    if (ret != FREEXL_OK)
      {

Added examples/test_xlsx.c.

























































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* 
/ test_xlsx.c
/
/ FreeXL Sample code
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "freexl.h"

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

int
main (int argc, char *argv[])
{
#ifdef OMIT_XMLDOC		/* XML support is not enabled */
    fprintf (stderr,
	     "Sorry, this version of test_xlsx was built by disabling support XML documents\n");
    return -1;
#else
    const void *handle;
    int ret;
    unsigned int sst_count;
    unsigned int worksheet_count;
    unsigned int idx;
    const char *string;
    int verbose = 0;

    if (argc == 2 || argc == 3)
      {
	  if (argc == 3)
	    {
		if (strcmp (argv[2], "-verbose") == 0)
		    verbose = 1;
	    }
      }
    else
      {
	  fprintf (stderr, "usage: test_xlsx path.xlsx [-verbose]\n");
	  return -1;
      }

/* opening the .XLSX file [Workbook] */
    ret = freexl_open_xlsx (argv[1], &handle);
    if (ret != FREEXL_OK)
      {
	  freexl_close_xlsx (handle);
	  fprintf (stderr, "OPEN ERROR: %d\n", ret);
	  return -1;
      }

/* XLSX Worksheet entries */
    ret = freexl_get_worksheets_count (handle, &worksheet_count);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "GET-WORKSHEETS-COUNT Error: %d\n", ret);
	  goto stop;
      }
    printf ("XLSX Worksheets .....: %u\n", worksheet_count);

    /* XLSX SST entries */
    ret = freexl_get_strings_count (handle, &sst_count);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "GET-STRINGS-COUNT] Error: %d\n", ret);
	  goto stop;
      }
    printf ("XLSX SST entries ....: %u\n", sst_count);

    printf
	("\nWorksheets:\n=========================================================\n");
    for (idx = 0; idx < worksheet_count; idx++)
      {
	  /* printing XLSX Worksheets entries */
	  unsigned short active;
	  unsigned int rows;
	  unsigned short columns;

	  ret = freexl_get_worksheet_name (handle, idx, &string);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-WORKSHEET-NAME Error: %d\n", ret);
		goto stop;
	    }
	  if (string == NULL)
	      printf ("%3u] NULL (unnamed)\n", idx);
	  else
	      printf ("%3u] %s\n", idx, string);
	  ret = freexl_select_active_worksheet (handle, idx);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "SELECT-ACTIVE_WORKSHEET Error: %d\n", ret);
		goto stop;
	    }
	  ret = freexl_get_active_worksheet (handle, &active);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-ACTIVE_WORKSHEET Error: %d\n", ret);
		goto stop;
	    }
	  printf
	      ("\tok, Worksheet successfully selected: currently active: %u\n",
	       active);
	  ret = freexl_worksheet_dimensions (handle, &rows, &columns);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "WORKSHEET-DIMENSIONS Error: %d\n", ret);
		goto stop;
	    }
	  printf ("\t%u Rows X %u Columns\n\n", rows, columns);
      }

    if (!verbose)
	goto stop;

/* printing XLSX SST entries */
    printf
	("\nSST [Shared String Table]:\n=========================================================\n");
    for (idx = 0; idx < sst_count; idx++)
      {
	  ret = freexl_get_SST_string (handle, idx, &string);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-SST-STRING Error: %d\n", ret);
		goto stop;
	    }
	  if (string == NULL)
	      printf ("%8u] NULL (empty string)\n", idx);
	  else
	      printf ("%8u] %s\n", idx, string);
      }

  stop:
/* closing the .XLSX file [Workbook] */
    ret = freexl_close (handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "CLOSE ERROR: %d\n", ret);
	  return -1;
      }

    return 0;
#endif /* end conditional XML support */
}

Added examples/xlsx2sql.c.























































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/* 
/ xlsx2sql.c
/
/ FreeXL Sample code
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "freexl.h"

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

#ifndef OMIT_XMLDOC		/* only if XML support is enabled */

static void
make_table_name (const char *prefix, unsigned short index, char *table_name)
{
/* generating an SQL clean table name */
    char buf[2048];
    char *in = buf;
    char *out = table_name;
    sprintf (buf, "%s_%02u", prefix, index);

/* masking for SQL */
    *out++ = '"';
    while (*in != '\0')
      {
	  if (*in == '"')
	      *out++ = '"';
	  *out++ = *in++;
      }
    *out++ = '"';
    *out = '\0';
}

static void
print_sql_string (const char *string)
{
/* printing a well formatted SQL string */
    const char *p = string;
    putchar (',');
    putchar (' ');
    putchar ('\'');
    while (*p != '\0')
      {
	  if (*p == '\'')
	    {
		/* masking any ' as '' */
		putchar ('\'');
	    }
	  putchar (*p);
	  p++;
      }
    putchar ('\'');
}

#endif /* end conditional XML support */

int
main (int argc, char *argv[])
{
#ifdef OMIT_XMLDOC		/* XML support is not enabled */
    fprintf (stderr,
	     "Sorry, this version of xlsx2sql was built by disabling support XML documents\n");
    return -1;
#else
    unsigned int worksheet_index;
    const char *table_prefix = "xlsx_table";
    char table_name[2048];
    const void *handle;
    int ret;
    unsigned int max_worksheet;
    unsigned int rows;
    unsigned short columns;
    unsigned int row;
    unsigned short col;

    if (argc == 2 || argc == 3)
      {
	  if (argc == 3)
	      table_prefix = argv[2];
      }
    else
      {
	  fprintf (stderr, "usage: xlsx2sql path.xlsx [table_prefix]\n");
	  return -1;
      }

/* opening the .XLSX file [Workbook] */
    ret = freexl_open_xlsx (argv[1], &handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "OPEN ERROR: %d\n", ret);
	  return -1;
      }

/* querying XLSX Worksheet entries */
    ret = freexl_get_worksheets_count (handle, &max_worksheet);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "GET-WORKSHEETS-COUNT Error: %d\n", ret);
	  goto stop;
      }

/* SQL output */
    printf ("--\n-- this SQL script was automatically created by xlsx2sql\n");
    printf ("--\n-- input .xls document was: %s\n--\n", argv[1]);
    printf ("\nBEGIN;\n\n");

    for (worksheet_index = 0; worksheet_index < max_worksheet;
	 worksheet_index++)
      {
	  const char *worsheet_name;
	  make_table_name (table_prefix, worksheet_index, table_name);
	  ret =
	      freexl_get_worksheet_name (handle, worksheet_index,
					 &worsheet_name);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "GET-WORKSHEET-NAME Error: %d\n", ret);
		goto stop;
	    }
	  /* selecting the active Worksheet */
	  ret = freexl_select_active_worksheet (handle, worksheet_index);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "SELECT-ACTIVE_WORKSHEET Error: %d\n", ret);
		goto stop;
	    }
	  /* dimensions */
	  ret = freexl_worksheet_dimensions (handle, &rows, &columns);
	  if (ret != FREEXL_OK)
	    {
		fprintf (stderr, "WORKSHEET-DIMENSIONS Error: %d\n", ret);
		goto stop;
	    }

	  printf ("--\n-- creating a DB table\n");
	  printf ("-- extracting data from Worksheet #%u: %s\n--\n",
		  worksheet_index, worsheet_name);
	  printf ("CREATE TABLE %s (\n", table_name);
	  printf ("\trow_no INTEGER NOT NULL PRIMARY KEY");
	  for (col = 0; col < columns; col++)
	      printf (",\n\tcol_%03u MULTITYPE", col);
	  printf (");\n");

	  printf ("--\n-- populating the same table\n--\n");
	  for (row = 0; row < rows; row++)
	    {
		/* INSERT INTO statements */
		FreeXL_CellValue cell;

		printf ("INSERT INTO %s (row_no", table_name);
		for (col = 0; col < columns; col++)
		    printf (", col_%03u", col);
		printf (") VALUES (%u", row);
		for (col = 0; col < columns; col++)
		  {
		      ret = freexl_get_cell_value (handle, row, col, &cell);
		      if (ret != FREEXL_OK)
			{
			    fprintf (stderr,
				     "CELL-VALUE-ERROR (r=%u c=%u): %d\n", row,
				     col, ret);
			    goto stop;
			}
		      switch (cell.type)
			{
			case FREEXL_CELL_INT:
			    printf (", %d", cell.value.int_value);
			    break;
			case FREEXL_CELL_DOUBLE:
			    printf (", %1.12f", cell.value.double_value);
			    break;
			case FREEXL_CELL_TEXT:
			case FREEXL_CELL_SST_TEXT:
			    print_sql_string (cell.value.text_value);
			    break;
			case FREEXL_CELL_DATE:
			case FREEXL_CELL_DATETIME:
			case FREEXL_CELL_TIME:
			    printf (", '%s'", cell.value.text_value);
			    break;
			case FREEXL_CELL_NULL:
			default:
			    printf (", NULL");
			    break;
			};
		  }
		printf (");\n");
	    }
	  printf ("\n-- done: table end\n\n\n\n");
      }
    printf ("COMMIT;\n");

  stop:
/* closing the .ODS file [Workbook] */
    ret = freexl_close (handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "CLOSE ERROR: %d\n", ret);
	  return -1;
      }

    return 0;
#endif /* end conditional XML support */
}

Changes to headers/freexl.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
292
293
294
295
296
297
298
299


















300
301
302
303
304
305
306
...
379
380
381
382
383
384
385
386




































387
388
389
390
391
392
393


394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412


413
414
415
416
417
















418
419
420




























421
422
423
424
425


426
427
428
429
430
431
432

433
434
435
436
437
438
439
...
456
457
458
459
460
461
462


463
464
465
466
467
468






























469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
...
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
/* 
/ freexl.h
/
/ public declarations
/
/ version  1.0, 2011 July 26
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
................................................................................
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2011
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ Brad Hards 
/
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
................................................................................
#define FREEXL_CELL_NULL		101
/** Cell contains an integer value */
#define FREEXL_CELL_INT			102
/** Cell contains a floating point number */
#define FREEXL_CELL_DOUBLE		103
/** Cell contains a text value */
#define FREEXL_CELL_TEXT		104
/** Cell contains a reference to a Single String Table entry (BIFF8) */
#define FREEXL_CELL_SST_TEXT		105
/** Cell contains a number intended to represent a date */
#define FREEXL_CELL_DATE		106
/** Cell contains a number intended to represent a date and time */
#define FREEXL_CELL_DATETIME		107
/** Cell contains a number intended to represent a time */
#define FREEXL_CELL_TIME		108
................................................................................
/** Information query for BIFF format count */
#define FREEXL_BIFF_FORMAT_COUNT	32012
/** Information query for BIFF extended format count */
#define FREEXL_BIFF_XF_COUNT		32013

/* Error codes */
#define FREEXL_OK			0 /**< No error, success */
#define FREEXL_FILE_NOT_FOUND		-1 /**< .xls file does not exist or is
						not accessible for reading */
#define FREEXL_NULL_HANDLE		-2 /**< Null xls_handle argument */
#define FREEXL_INVALID_HANDLE		-3 /**< Invalid xls_handle argument */
#define FREEXL_INSUFFICIENT_MEMORY	-4 /**< some kind of memory allocation
                                                failure */
#define FREEXL_NULL_ARGUMENT		-5 /**< an unexpected null argument */
#define FREEXL_INVALID_INFO_ARG		-6 /**< invalid "what" parameter */
#define FREEXL_INVALID_CFBF_HEADER	-7 /**< the .xls file does not contain a
                                                valid CFBF header */
#define FREEXL_CFBF_READ_ERROR		-8 /**< Read error. Usually indicates a
................................................................................
#define FREEXL_CFBF_ILLEGAL_MINI_FAT_ENTRY	-25 /**< The MiniFAT stream 
                                                     contains an invalid entry.
                                                     Possibly a corrupt file. */
#define FREEXL_CRAFTED_FILE			-26 /**< A severely corrupted file
                                                 (may be purposely crafted for 
                                                 malicious purposes) has been 
                                                 detected. */




















    /**
     Container for a cell value
     
     freexl_get_cell_value() takes a pointer to this structure, and fills
     in the appropriate values.
     
................................................................................
     */
    FREEXL_DECLARE const char *freexl_version (void);

    /**
     Open the .xls file, preparing for future functions
     
     \param path full or relative pathname of the input .xls file.
     \param xls_handle an opaque reference (handle) to be used in each




































     subsequent function (return value).

     \return FREEXL_OK will be returned on success, otherwise any appropriate
     error code on failure.

     \note You are expected to freexl_close() even on failure, so as to
     correctly release any dynamic memory allocation.


     */
    FREEXL_DECLARE int freexl_open (const char *path, const void **xls_handle);


    /**
     Open the .xls file for metadata query only
     
     This is similar to freexl_open(), except that an abbreviated parsing
     step is performed. This makes it faster, but does not support queries
     for cell values. 
     
     \param path full or relative pathname of the input .xls file.
     \param xls_handle an opaque reference (handle) to be used in each
     subsequent function (return value).

     \return FREEXL_OK will be returned on success, otherwise any appropriate
     error code on failure.

     \note You are expected to freexl_close() even on failure, so as to
     correctly release any dynamic memory allocation.


     */
    FREEXL_DECLARE int freexl_open_info (const char *path,
					 const void **xls_handle);

    /** 
















     Close the .xls file and releasing any allocated resource

    \param xls_handle the handle previously returned by freexl_open()





























    \return FREEXL_OK will be returned on success
    
    \note After calling freexl_close() any related resource will be released,
    and the handle will no longer be valid.


    */
    FREEXL_DECLARE int freexl_close (const void *xls_handle);

    /**
     Query general information about the Workbook and Worksheets

     \param xls_handle the handle previously returned by freexl_open()

     \param what the info to be queried.
     \param info the corresponding information value (return value)
     
     \note FREEXL_UNKNOWN will be returned in \p info if the information is 
     not available, not appropriate or not supported for the file type.
     
     \return FREEXL_OK will be returned on success
................................................................................
    FREEXL_BIFF_CP*,FREEXL_BIFF_UTF16LE
    or FREEXL_BIFF_MACROMAN)
    - FREEXL_BIFF_SHEET_COUNT (returning the total number of worksheets)
    - FREEXL_BIFF_STRING_COUNT (returning the total number of Single String
    Table entries)
    - FREEXL_BIFF_FORMAT_COUNT (returning the total number of format entries)
    - FREEXL_BIFF_XF_COUNT (returning the number of extended format entries)


    */
    FREEXL_DECLARE int freexl_get_info (const void *xls_handle,
					unsigned short what,
					unsigned int *info);

    /**






























     Query worksheet name

    \param xls_handle the handle previously returned by freexl_open()
    \param sheet_index the index identifying the worksheet (base 0)
    \param string the name of the worksheet (return value)
    
    \return FREEXL_OK will be returned on success
    */
    FREEXL_DECLARE int freexl_get_worksheet_name (const void *xls_handle,
						  unsigned short sheet_index,
						  const char **string);

    /**
     Set the currently active worksheets
      
     Within a FreeXL handle, only one worksheet can be active at a time.
     Functions that fetch data are implictly working on the selected worksheet.

     \param xls_handle the handle previously returned by freexl_open()
     \param sheet_index the index identifying the worksheet (base 0)
     
     \return FREEXL_OK will be returned on success
     */
    FREEXL_DECLARE int freexl_select_active_worksheet (const void *xls_handle,

						       unsigned short
						       sheet_index);

    /**
     Query the currently active worksheet index
     
     \param xls_handle the handle previously returned by freexl_open()
     \param sheet_index the index corresponding to the currently active
     Worksheet (return value)
     
     \return FREEXL_OK will be returned on success
     
     \sa freexl_select_active_worksheet() for how to select the worksheet
    */
    FREEXL_DECLARE int freexl_get_active_worksheet (const void *xls_handle,
						    unsigned short
						    *sheet_index);

    /**
     Query worksheet dimensions
     
     This function returns the number of rows and columns for the currently
     selected worksheet. 

     \param xls_handle the handle previously returned by freexl_open()
     \param rows the total row count (return value)
     \param columns the total column count (return value)

     \return FREEXL_OK will be returned on success

     \note Worksheet dimensions are zero based, so if you
     have a worksheet that is four columns and two rows (i.e. from A1 in the
     top left corner to B4 in the bottom right corner), this will return rows
     equal to 1 and columns equal to 3). This is to support C style looping.
     */
    FREEXL_DECLARE int freexl_worksheet_dimensions (const void *xls_handle,
						    unsigned int *rows,
						    unsigned short *columns);

    /**
     Retrieve string entries from SST
     
     \param xls_handle the handle previously returned by freexl_open()
     \param string_index the index identifying the String entry (base 0).
     \param string the corresponding String value (return value)
     
     \return FREEXL_OK will be returned on success
     
     \note This function is not normally required, since freexl_get_cell_value
     will return the string where appropriate. It is mainly intended for
     debugging purposes.
     
    */
    FREEXL_DECLARE int freexl_get_SST_string (const void *xls_handle,
					      unsigned short string_index,
					      const char **string);

    /**
     Retrieve FAT entries from FAT chain

     \param xls_handle the handle previously returned by freexl_open()
     \param sector_index the index identifying the Sector entry (base 0).
     \param next_sector_index the index identifying the next Sector to be
     accessed in logical order (return value).
    
     \note The following values imply special meaning:
     - 0xffffffff free / unused sector
     - 0xfffffffe end of chain
................................................................................
     \return FREEXL_OK will be returned on success

     \note This function is not normally required, since FreeXL will handle
     FAT table entries transparent to the user. It is mainly intended for
     debugging purposes.
     
     */
    FREEXL_DECLARE int freexl_get_FAT_entry (const void *xls_handle,
					     unsigned int sector_index,
					     unsigned int *next_sector_index);

    /**
     Retrieve individual cell values from the currently active worksheet 

     \param xls_handle the handle previously returned by freexl_open()
     \param row row number of the cell to query (zero base)
     \param column column number of the cell to query (zero base)
     \param value the cell type and value (return value)

     \return FREEXL_OK will be returned on success
    */
    FREEXL_DECLARE int freexl_get_cell_value (const void *xls_handle,
					      unsigned int row,
					      unsigned short column,
					      FreeXL_CellValue * value);

#ifdef __cplusplus
}
#endif

#endif				/* _FREEXL_H */





|







 







|







 







|







 







|

|
|







 







<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>

|
>









|







>
>


|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

>
>

|


|

|
>







 







>
>

|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|





|









|




|
>






|





|

|









|










|






|










|






|







 







|






|






|









1
2
3
4
5
6
7
8
9
10
11
12
13
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
...
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
/* 
/ freexl.h
/
/ public declarations
/
/ version  2.0, 2021 June 10
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
................................................................................
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2011-2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ Brad Hards 
/
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
................................................................................
#define FREEXL_CELL_NULL		101
/** Cell contains an integer value */
#define FREEXL_CELL_INT			102
/** Cell contains a floating point number */
#define FREEXL_CELL_DOUBLE		103
/** Cell contains a text value */
#define FREEXL_CELL_TEXT		104
/** Cell contains a reference to a String */
#define FREEXL_CELL_SST_TEXT		105
/** Cell contains a number intended to represent a date */
#define FREEXL_CELL_DATE		106
/** Cell contains a number intended to represent a date and time */
#define FREEXL_CELL_DATETIME		107
/** Cell contains a number intended to represent a time */
#define FREEXL_CELL_TIME		108
................................................................................
/** Information query for BIFF format count */
#define FREEXL_BIFF_FORMAT_COUNT	32012
/** Information query for BIFF extended format count */
#define FREEXL_BIFF_XF_COUNT		32013

/* Error codes */
#define FREEXL_OK			0 /**< No error, success */
#define FREEXL_FILE_NOT_FOUND		-1 /**< .xls or .xlsx file does not exist or is
						not accessible for reading */
#define FREEXL_NULL_HANDLE		-2 /**< Null freexl_handle argument */
#define FREEXL_INVALID_HANDLE		-3 /**< Invalid freexl_handle argument */
#define FREEXL_INSUFFICIENT_MEMORY	-4 /**< some kind of memory allocation
                                                failure */
#define FREEXL_NULL_ARGUMENT		-5 /**< an unexpected null argument */
#define FREEXL_INVALID_INFO_ARG		-6 /**< invalid "what" parameter */
#define FREEXL_INVALID_CFBF_HEADER	-7 /**< the .xls file does not contain a
                                                valid CFBF header */
#define FREEXL_CFBF_READ_ERROR		-8 /**< Read error. Usually indicates a
................................................................................
#define FREEXL_CFBF_ILLEGAL_MINI_FAT_ENTRY	-25 /**< The MiniFAT stream 
                                                     contains an invalid entry.
                                                     Possibly a corrupt file. */
#define FREEXL_CRAFTED_FILE			-26 /**< A severely corrupted file
                                                 (may be purposely crafted for 
                                                 malicious purposes) has been 
                                                 detected. */

#define FREEXL_INVALID_XLSX			-27 /**< The file doesn't seems to be a
												valid XLSX document */
#define FREEXL_XLSX_ILLEGAL_SHEET_INDEX	-28 /**< The requested worksheet is not
                                                 available in the workbook */
#define FREEXL_XSLX_UNSELECTED_SHEET	-29 /**< There is no currently active
                                              worksheet. Possibly a forgotten
                                              call to 
                                              freexl_select_active_worksheet() */
#define FREEXL_XLSX_INVALID_SST		-30 /**< The file contains an invalid
                                                 Single String Table */
#define FREEXL_XLSX_ILLEGAL_SST_INDEX	-31 /**< The requested Single String 
                                                 Table entry is not available */
#define FREEXL_ODS_ILLEGAL_SHEET_INDEX	-32 /**< The requested worksheet is not
                                                 available in the workbook */
#define FREEXL_ODS_UNSELECTED_SHEET	-33 /**< There is no currently active
                                              worksheet. Possibly a forgotten
                                              call to 
                                              freexl_select_active_worksheet() */

    /**
     Container for a cell value
     
     freexl_get_cell_value() takes a pointer to this structure, and fills
     in the appropriate values.
     
................................................................................
     */
    FREEXL_DECLARE const char *freexl_version (void);

    /**
     Open the .xls file, preparing for future functions
     
     \param path full or relative pathname of the input .xls file.
     \param freexl_handle an opaque reference (handle) to be used in each
     subsequent function (return value).

     \return FREEXL_OK will be returned on success, otherwise any appropriate
     error code on failure.

     \note You are expected to freexl_close() even on failure, so as to
     correctly release any dynamic memory allocation.
     
     \sa freexl_open_xlsx, freexl_open_ods, freexl_open_info, freexl_close.
     */
    FREEXL_DECLARE int freexl_open (const char *path,
				    const void **freexl_handle);

    /**
     Open the .xlsx file, preparing for future functions
     
     \param path full or relative pathname of the input .xlsx file.
     \param freexl_handle an opaque reference (handle) to be used in each
     subsequent function (return value).

     \return FREEXL_OK will be returned on success, otherwise any appropriate
     error code on failure.

     \note You are expected to freexl_close() even on failure, so as to
     correctly release any dynamic memory allocation.
     
     \sa freexl_open, freexl_open_ods, freexl_close.
     */
    FREEXL_DECLARE int freexl_open_xlsx (const char *path,
					 const void **freexl_handle);

    /**
     Open the .ods file, preparing for future functions
     
     \param path full or relative pathname of the input .ods file.
     \param freexl_handle an opaque reference (handle) to be used in each
     subsequent function (return value).

     \return FREEXL_OK will be returned on success, otherwise any appropriate
     error code on failure.

     \note You are expected to freexl_close() even on failure, so as to
     correctly release any dynamic memory allocation.
     
     \sa freexl_open, freexl_open_xlsx, freexl_close.
     */
    FREEXL_DECLARE int freexl_open_ods (const char *path,
					const void **freexl_handle);

    /**
     Open the .xls file for metadata query only
     
     This is similar to freexl_open(), except that an abbreviated parsing
     step is performed. This makes it faster, but does not support queries
     for cell values. 
     
     \param path full or relative pathname of the input .xls file.
     \param freexl_handle an opaque reference (handle) to be used in each
     subsequent function (return value).

     \return FREEXL_OK will be returned on success, otherwise any appropriate
     error code on failure.

     \note You are expected to freexl_close() even on failure, so as to
     correctly release any dynamic memory allocation.
     
     \sa freexl_open, freexl_close, freexl_close_xls
     */
    FREEXL_DECLARE int freexl_open_info (const char *path,
					 const void **freexl_handle);

    /** 
     Closing the FREEXL file and releasing any allocated resource

    \param freexl_handle the handle previously returned by freexl_open(),
    freexl_open_xlsx() or freexl_open_ods()

    \return FREEXL_OK will be returned on success
    
    \note this function is just a convenience method that will automatically
    dispatch freexl_close_xls() or freexl_close_xlsx() or even freexl_close_ods() 
    accordingly to the actual type of the passed handle.
     
    \sa freexl_close_xls, freexl_close_xlsx, freexl_close_ods
    */
    FREEXL_DECLARE int freexl_close (const void *freexl_handle);

    /** 
     Closing the XLS file and releasing any allocated resource

    \param freexl_handle the handle previously returned by freexl_open()

    \return FREEXL_OK will be returned on success
    
    \note After calling freexl_close_xls() any related resource will be released,
    and the handle will no longer be valid.
    * 
    \sa freexl_close, freexl_close_xlsx, freexl_close_ods
    */
    FREEXL_DECLARE int freexl_close_xls (const void *freexl_handle);

    /** 
     Closing the XLSX file and releasing any allocated resource

    \param freexl_handle the handle previously returned by freexl_open_xlsx()

    \return FREEXL_OK will be returned on success
    
    \note After calling freexl_close_xlsx() any related resource will be released,
    and the handle will no longer be valid.
    * 
    \sa freexl_close, freexl_close_xls, freexl_close_ods
    */
    FREEXL_DECLARE int freexl_close_xlsx (const void *freexl_handle);

    /** 
     Closing the ODS file and releasing any allocated resource

    \param freexl_handle the handle previously returned by freexl_open_ods()

    \return FREEXL_OK will be returned on success
    
    \note After calling freexl_close_ods() any related resource will be released,
    and the handle will no longer be valid.
    * 
    \sa freexl_close, freexl_close_xls, freexl_close_xlsx
    */
    FREEXL_DECLARE int freexl_close_ods (const void *freexl_handle);

    /**
     Query general information about the Workbook and Worksheets - XLS

     \param freexl_handle the handle previously returned by freexl_open()
     or freexl_open_info()
     \param what the info to be queried.
     \param info the corresponding information value (return value)
     
     \note FREEXL_UNKNOWN will be returned in \p info if the information is 
     not available, not appropriate or not supported for the file type.
     
     \return FREEXL_OK will be returned on success
................................................................................
    FREEXL_BIFF_CP*,FREEXL_BIFF_UTF16LE
    or FREEXL_BIFF_MACROMAN)
    - FREEXL_BIFF_SHEET_COUNT (returning the total number of worksheets)
    - FREEXL_BIFF_STRING_COUNT (returning the total number of Single String
    Table entries)
    - FREEXL_BIFF_FORMAT_COUNT (returning the total number of format entries)
    - FREEXL_BIFF_XF_COUNT (returning the number of extended format entries)
     
    \note will only work when the handle if of the XLS type.
    */
    FREEXL_DECLARE int freexl_get_info (const void *freexl_handle,
					unsigned short what,
					unsigned int *info);

    /**
     Querying how many Single Strings are in the Workbook

     \param freexl_handle the handle previously returned by freexl_open()
     or freexl_open_xlsx but not by freexl_open_ods()
     \param info the corresponding information value (return value)
     
     \note FREEXL_UNKNOWN will be returned in \p info if the information is 
     not available, not appropriate or not supported for the file type.
     
     \return FREEXL_OK will be returned on success
    */
    FREEXL_DECLARE int freexl_get_strings_count (const void *freexl_handle,
						 unsigned int *info);

    /**
     Querying how many Worksheets are in the Workbook

     \param freexl_handle the handle previously returned by freexl_open()
     or freexl_open_xlsx or either freexl_open_ods()
     \param info the corresponding information value (return value)
     
     \note FREEXL_UNKNOWN will be returned in \p info if the information is 
     not available, not appropriate or not supported for the file type.
     
     \return FREEXL_OK will be returned on success
    */
    FREEXL_DECLARE int freexl_get_worksheets_count (const void *freexl_handle,
						    unsigned int *info);

    /**
     Query worksheet name

    \param freexl_handle the handle previously returned by freexl_open()
    \param sheet_index the index identifying the worksheet (base 0)
    \param string the name of the worksheet (return value)
    
    \return FREEXL_OK will be returned on success
    */
    FREEXL_DECLARE int freexl_get_worksheet_name (const void *freexl_handle,
						  unsigned short sheet_index,
						  const char **string);

    /**
     Set the currently active worksheets
      
     Within a FreeXL handle, only one worksheet can be active at a time.
     Functions that fetch data are implictly working on the selected worksheet.

     \param freexl_handle the handle previously returned by freexl_open()
     \param sheet_index the index identifying the worksheet (base 0)
     
     \return FREEXL_OK will be returned on success
     */
    FREEXL_DECLARE int freexl_select_active_worksheet (const void
						       *freexl_handle,
						       unsigned short
						       sheet_index);

    /**
     Query the currently active worksheet index
     
     \param freexl_handle the handle previously returned by freexl_open()
     \param sheet_index the index corresponding to the currently active
     Worksheet (return value)
     
     \return FREEXL_OK will be returned on success
     
     \sa freexl_select_active_worksheet for how to select the worksheet
    */
    FREEXL_DECLARE int freexl_get_active_worksheet (const void *freexl_handle,
						    unsigned short
						    *sheet_index);

    /**
     Query worksheet dimensions
     
     This function returns the number of rows and columns for the currently
     selected worksheet. 

     \param freexl_handle the handle previously returned by freexl_open()
     \param rows the total row count (return value)
     \param columns the total column count (return value)

     \return FREEXL_OK will be returned on success

     \note Worksheet dimensions are zero based, so if you
     have a worksheet that is four columns and two rows (i.e. from A1 in the
     top left corner to B4 in the bottom right corner), this will return rows
     equal to 1 and columns equal to 3). This is to support C style looping.
     */
    FREEXL_DECLARE int freexl_worksheet_dimensions (const void *freexl_handle,
						    unsigned int *rows,
						    unsigned short *columns);

    /**
     Retrieve string entries from SST
     
     \param freexl_handle the handle previously returned by freexl_open()
     \param string_index the index identifying the String entry (base 0).
     \param string the corresponding String value (return value)
     
     \return FREEXL_OK will be returned on success
     
     \note This function is not normally required, since freexl_get_cell_value
     will return the string where appropriate. It is mainly intended for
     debugging purposes.
     
    */
    FREEXL_DECLARE int freexl_get_SST_string (const void *freexl_handle,
					      unsigned short string_index,
					      const char **string);

    /**
     Retrieve FAT entries from FAT chain

     \param feexl_handle the handle previously returned by freexl_open()
     \param sector_index the index identifying the Sector entry (base 0).
     \param next_sector_index the index identifying the next Sector to be
     accessed in logical order (return value).
    
     \note The following values imply special meaning:
     - 0xffffffff free / unused sector
     - 0xfffffffe end of chain
................................................................................
     \return FREEXL_OK will be returned on success

     \note This function is not normally required, since FreeXL will handle
     FAT table entries transparent to the user. It is mainly intended for
     debugging purposes.
     
     */
    FREEXL_DECLARE int freexl_get_FAT_entry (const void *freexl_handle,
					     unsigned int sector_index,
					     unsigned int *next_sector_index);

    /**
     Retrieve individual cell values from the currently active worksheet 

     \param freexl_handle the handle previously returned by freexl_open()
     \param row row number of the cell to query (zero base)
     \param column column number of the cell to query (zero base)
     \param value the cell type and value (return value)

     \return FREEXL_OK will be returned on success
    */
    FREEXL_DECLARE int freexl_get_cell_value (const void *freexl_handle,
					      unsigned int row,
					      unsigned short column,
					      FreeXL_CellValue * value);

#ifdef __cplusplus
}
#endif

#endif				/* _FREEXL_H */

Changes to headers/freexl_internals.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
..
79
80
81
82
83
84
85























86
87
88
89
90
91
92
...
286
287
288
289
290
291
292








































































































































































/* 
/ freexl_internals.h
/
/ internal declarations
/
/ version  1.0, 2011 July 26
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
................................................................................
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2011
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ Brad Hards
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
................................................................................
#define BIFF_LABEL		0x0204
#define BIFF_LABEL_SST		0x00FD
#define BIFF_RK			0x027E
#define BIFF_MULRK		0x00BD
#define BIFF_BOOLERR_2	0x0005
#define BIFF_BOOLERR	0x0205
























typedef union biff_word
{
    unsigned char bytes[2];
    unsigned short value;
} biff_word16;

typedef union biff_double_word
................................................................................
    int second_pass;		/* set to 1=TRUE for pass #2 */
    biff_format format_array[BIFF_MAX_FORMAT];	/* the array for DATE/DATETIME/TIME formats */
    unsigned short max_format_index;	/* max array index [formats] */
    unsigned short biff_xf_array[BIFF_MAX_XF];	/* the array for XF/Format association */
    unsigned short biff_xf_next_index;	/* next XF index */
    int magic2;			/* magic signature #2 */
} biff_workbook;













































































































































































|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
/* 
/ freexl_internals.h
/
/ internal declarations
/
/ version  1.0, 2.0, 2021 June 10
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
................................................................................
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2011-2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ Brad Hards
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
................................................................................
#define BIFF_LABEL		0x0204
#define BIFF_LABEL_SST		0x00FD
#define BIFF_RK			0x027E
#define BIFF_MULRK		0x00BD
#define BIFF_BOOLERR_2	0x0005
#define BIFF_BOOLERR	0x0205

/* XLSX data types */
#define XLSX_NULL		1
#define XLSX_INTEGER	2
#define XLSX_DOUBLE		3
#define XLSX_STR_INDEX	4
#define XLSX_DATETIME	5

#define XLSX_DATE_NONE		0
#define XLSX_DATE_SIMPLE	1
#define XLSX_TIME_SIMPLE	2
#define XLSX_DATE_AND_TIME	3

/* ODS data types */
#define ODS_VOID		1
#define ODS_FLOAT		2
#define ODS_CURRENCY	3
#define ODS_PERCENTAGE	4
#define ODS_BOOLEAN		5
#define ODS_DATE		6
#define ODS_TIME		7
#define ODS_STRING		8
#define ODS_INTEGER		9

typedef union biff_word
{
    unsigned char bytes[2];
    unsigned short value;
} biff_word16;

typedef union biff_double_word
................................................................................
    int second_pass;		/* set to 1=TRUE for pass #2 */
    biff_format format_array[BIFF_MAX_FORMAT];	/* the array for DATE/DATETIME/TIME formats */
    unsigned short max_format_index;	/* max array index [formats] */
    unsigned short biff_xf_array[BIFF_MAX_XF];	/* the array for XF/Format association */
    unsigned short biff_xf_next_index;	/* next XF index */
    int magic2;			/* magic signature #2 */
} biff_workbook;

typedef struct xlsx_cell_struct
{
/* a struct representing a XLSX cell */
    int col_no;
    int type;
    int is_datetime;
    int assigned;
    int int_value;
    double dbl_value;
    int str_index;
    struct xlsx_cell_struct *next;
} xlsx_cell;

typedef struct xlsx_row_struct
{
/* a struct representing a XLSX row of cells */
    int row_no;
    int max_cell;
    xlsx_cell *first;
    xlsx_cell *last;
    struct xlsx_row_struct *next;
} xlsx_row;

typedef struct xlsx_worksheet_struct
{
/* a struct representing a XLSX Worksheet */
    int id;
    char *name;
    xlsx_row *first;
    xlsx_row *last;
    int max_row;
    int max_cell;
    int error;
    char *CharData;
    int CharDataLen;
    int CharDataMax;
    int CharDataStep;
    int RowOk;
    int ColOk;
    int CellValueOk;
    struct xlsx_workbook_struct *wbRef;
    struct xlsx_worksheet_struct *next;
} xlsx_worksheet;

typedef struct xlsx_format_struct
{
/* a struct representing a XLSX format */
    int fmtId;
    int is_datetime;
} xlsx_format;

typedef struct xlsx_style_struct
{
/* a struct representing a XLSX Cell Style */
    int stlId;
    xlsx_format *formatRef;
} xlsx_style;

typedef struct xml_datetime_struct
{
/* a struct intended to store a block of DataTime strings */
#define MAX_DATETIME_STR	128
#define STR_DATETIME_LEN	20
    char datetime[MAX_DATETIME_STR][STR_DATETIME_LEN];
    int next_str;
    struct xml_datetime_struct *next;
} xml_datetime;

typedef struct xlsx_workbook_struct
{
/* a struct representing a XLSX Workbook */
    xlsx_worksheet *first;
    xlsx_worksheet *last;
    xlsx_worksheet *active_sheet;	/* currently active SHEET */
    int n_strings;
    int xml_strings;
    char **strings;
    int n_formats;
    int next_format;
    xlsx_format *formats;
    int n_styles;
    int next_style;
    xlsx_style *styles;
    xml_datetime *first_date;
    xml_datetime *last_date;
    int error;
    char *SharedStringsZipEntry;
    char *WorkbookZipEntry;
    char *StylesZipEntry;
    char *CharData;
    int CharDataLen;
    int CharDataMax;
    int CharDataStep;
    int SharedStringsOk;
    int WorksheetsOk;
    int StylesOk;
    int FormatsOk;
    int CellStylesOk;
} xlsx_workbook;

typedef struct ods_cell_struct
{
/* a struct representing an ODS cell */
    int col_no;
    int type;
    int assigned;
    int int_value;
    double dbl_value;
    char *txt_value;
    struct ods_cell_struct *next;
} ods_cell;

typedef struct ods_row_struct
{
/* a struct representing an ODS row of cells */
    int row_no;
    int max_cell;
    ods_cell *first;
    ods_cell *last;
    int NextColNo;
    struct ods_row_struct *next;
} ods_row;

typedef struct ods_worksheet_struct
{
/* a struct representing an ODS Worksheet */
    int id;
    char *name;
    int n_columns;
    ods_row *first;
    ods_row *last;
    int max_row;
    int max_cell;
    int RowOk;
    int ColOk;
    int CellValueOk;
    int NextRowNo;
    struct ods_worksheet_struct *next;
} ods_worksheet;

typedef struct ods_workbook_struct
{
/* a struct representing an ODS Workbook */
    ods_worksheet *first;
    ods_worksheet *last;
    ods_worksheet *active_sheet;	/* currently active SHEET */
    xml_datetime *first_date;
    xml_datetime *last_date;
    int error;
    char *ContentZipEntry;
    char *CharData;
    int CharDataLen;
    int CharDataMax;
    int CharDataStep;
    int ContentOk;
    int NextWorksheetId;
} ods_workbook;

typedef struct freexl_handle_struct
{
/* 
 * a generic handle to an XLS or XLSX or ODS spreadsheet
 */
    biff_workbook *xls_handle;
    xlsx_workbook *xlsx_handle;
    ods_workbook *ods_handle;
} freexl_handle;

Changes to makefile.vc.

1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17
18






19
20
21
22
23
24
25
26
27



28
29
30
31
32
33
34
35
# $Id: makefile.vc 2011/08/17 Sandro Furieri $
#
# NMAKE Makefile to build libfreexl on Windows
#
!INCLUDE nmake.opt





LIBOBJ	               =	freexl.obj
FREEXL_DLL	 	       =	freexl$(VERSION).dll

CFLAGS	=	/nologo -I. -Iheaders -IC:\OSGeo4W\include $(OPTFLAGS)

default:	all

all: freexl.lib freexl_i.lib

$(LIBOBJ):	src\freexl.c
	cl $(CFLAGS) src\freexl.c /c







freexl.lib:	$(LIBOBJ)
	if exist freexl.lib del freexl.lib
	lib /out:freexl.lib $(LIBOBJ)

$(FREEXL_DLL):	freexl_i.lib

freexl_i.lib:	$(LIBOBJ)
	link /debug /dll /out:$(FREEXL_DLL) \
		/implib:freexl_i.lib $(LIBOBJ) \



		C:\OSGeo4w\lib\iconv.lib
	if exist $(FREEXL_DLL).manifest mt -manifest \
		$(FREEXL_DLL).manifest -outputresource:$(FREEXL_DLL);2 

clean:
	del *.dll
	del *.exp
	del *.manifest
|

|



>
>
>
>
|








|


>
>
>
>
>
>









>
>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# $Id: makefile.vc 2021/06/11 Sandro Furieri $
#
# NMAKE Makefile to build libfreexl 2.0 on Windows
#
!INCLUDE nmake.opt

CORE				   = freexl.obj
XLSX				   = freexl_xlsx.obj
ODS					   = freexl_ods.obj

LIBOBJ	               =	$(CORE) $(XLSX) $(ODS)
FREEXL_DLL	 	       =	freexl$(VERSION).dll

CFLAGS	=	/nologo -I. -Iheaders -IC:\OSGeo4W\include $(OPTFLAGS)

default:	all

all: freexl.lib freexl_i.lib

$(CORE):	src\freexl.c
	cl $(CFLAGS) src\freexl.c /c

$(XLSX):	src\freexl_xlsx.c
	cl $(CFLAGS) src\freexl_xlsx.c /c

$(ODS):	src\freexl_ods.c
	cl $(CFLAGS) src\freexl_ods.c /c

freexl.lib:	$(LIBOBJ)
	if exist freexl.lib del freexl.lib
	lib /out:freexl.lib $(LIBOBJ)

$(FREEXL_DLL):	freexl_i.lib

freexl_i.lib:	$(LIBOBJ)
	link /debug /dll /out:$(FREEXL_DLL) \
		/implib:freexl_i.lib $(LIBOBJ) \
		C:\OSGeo4W\lib\iconv.lib \
		C:\OSGeo4W\lib\libexpat.lib \
		C:\OSGeo4W\lib\libminizip.lib \
		C:\OSGeo4w\lib\zlib.lib
	if exist $(FREEXL_DLL).manifest mt -manifest \
		$(FREEXL_DLL).manifest -outputresource:$(FREEXL_DLL);2 

clean:
	del *.dll
	del *.exp
	del *.manifest

Changes to makefile64.vc.

1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17
18






19
20
21
22
23
24
25
26
27
28



29
30
31
32
33
34
35
# $Id: makefile.vc 2011/08/17 Sandro Furieri $
#
# NMAKE Makefile to build libfreexl on Windows
#
!INCLUDE nmake64.opt





LIBOBJ	               =	freexl.obj
FREEXL_DLL	 	       =	freexl$(VERSION).dll

CFLAGS	=	/nologo -I. -Iheaders -IC:\OSGeo4W64\include $(OPTFLAGS)

default:	all

all: freexl.lib freexl_i.lib

$(LIBOBJ):	src\freexl.c
	cl $(CFLAGS) src\freexl.c /c







freexl.lib:	$(LIBOBJ)
	if exist freexl.lib del freexl.lib
	lib /out:freexl.lib $(LIBOBJ)

$(FREEXL_DLL):	freexl_i.lib

freexl_i.lib:	$(LIBOBJ)
	link /debug /dll /out:$(FREEXL_DLL) \
		/implib:freexl_i.lib $(LIBOBJ) \
		C:\OSGeo4w64\lib\iconv.lib



	if exist $(FREEXL_DLL).manifest mt -manifest \
		$(FREEXL_DLL).manifest -outputresource:$(FREEXL_DLL);2 

clean:
	del *.dll
	del *.exp
	del *.manifest
|





>
>
>
>
|








|


>
>
>
>
>
>









|
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# $Id: makefile.vc 2021/06/11 Sandro Furieri $
#
# NMAKE Makefile to build libfreexl on Windows
#
!INCLUDE nmake64.opt

CORE				   = freexl.obj
XLSX				   = freexl_xlsx.obj
ODS					   = freexl_ods.obj

LIBOBJ	               =	$(CORE) $(XLSX) $(ODS)
FREEXL_DLL	 	       =	freexl$(VERSION).dll

CFLAGS	=	/nologo -I. -Iheaders -IC:\OSGeo4W64\include $(OPTFLAGS)

default:	all

all: freexl.lib freexl_i.lib

$(CORE):	src\freexl.c
	cl $(CFLAGS) src\freexl.c /c

$(XLSX):	src\freexl_xlsx.c
	cl $(CFLAGS) src\freexl_xlsx.c /c

$(ODS):	src\freexl_ods.c
	cl $(CFLAGS) src\freexl_ods.c /c

freexl.lib:	$(LIBOBJ)
	if exist freexl.lib del freexl.lib
	lib /out:freexl.lib $(LIBOBJ)

$(FREEXL_DLL):	freexl_i.lib

freexl_i.lib:	$(LIBOBJ)
	link /debug /dll /out:$(FREEXL_DLL) \
		/implib:freexl_i.lib $(LIBOBJ) \
		C:\OSGeo4w64\lib\iconv.lib \
		C:\OSGeo4W64\lib\libexpat.lib \
		C:\OSGeo4W64\lib\libminizip.lib \
		C:\OSGeo4w64\lib\zlib.lib
	if exist $(FREEXL_DLL).manifest mt -manifest \
		$(FREEXL_DLL).manifest -outputresource:$(FREEXL_DLL);2 

clean:
	del *.dll
	del *.exp
	del *.manifest

Changes to src/Makefile.am.

1
2
3
4
5
6
7
8
9
10
11
12
13

AM_CPPFLAGS = -I$(top_srcdir)/headers
AM_CPPFLAGS += -I$(top_srcdir)

lib_LTLIBRARIES = libfreexl.la 

libfreexl_la_SOURCES = freexl.c

libfreexl_la_LDFLAGS = -version-info 2:0:1 -no-undefined

libfreexl_la_LIBADD = -lm

MOSTLYCLEANFILES = *.gcna *.gcno *.gcda






|

|




1
2
3
4
5
6
7
8
9
10
11
12
13

AM_CPPFLAGS = -I$(top_srcdir)/headers
AM_CPPFLAGS += -I$(top_srcdir)

lib_LTLIBRARIES = libfreexl.la 

libfreexl_la_SOURCES = freexl.c freexl_xlsx.c freexl_ods.c

libfreexl_la_LDFLAGS = -version-info 3:0:0 -no-undefined

libfreexl_la_LIBADD = -lm

MOSTLYCLEANFILES = *.gcna *.gcno *.gcda

Changes to src/Makefile.in.

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
...
405
406
407
408
409
410
411


412
413
414
415
416
417
418
...
569
570
571
572
573
574
575


576
577
578
579
580
581
582
...
615
616
617
618
619
620
621


622
623
624
625
626
627
628
    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
         $(am__cd) "$$dir" && rm -f $$files; }; \
  }
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libfreexl_la_DEPENDENCIES =
am_libfreexl_la_OBJECTS = freexl.lo
libfreexl_la_OBJECTS = $(am_libfreexl_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 
libfreexl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
................................................................................
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/freexl.Plo

am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
................................................................................
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/headers -I$(top_srcdir)
lib_LTLIBRARIES = libfreexl.la 
libfreexl_la_SOURCES = freexl.c
libfreexl_la_LDFLAGS = -version-info 2:0:1 -no-undefined
libfreexl_la_LIBADD = -lm
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
................................................................................
mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freexl.Plo@am__quote@ # am--include-marker



$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

................................................................................
clean: clean-am

clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
	mostlyclean-am

distclean: distclean-am
		-rm -f ./$(DEPDIR)/freexl.Plo


	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:
................................................................................

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f ./$(DEPDIR)/freexl.Plo


	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool







|







 







|
>







 







|
|







 







>
>







 







>
>







 







>
>







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
...
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
...
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
         $(am__cd) "$$dir" && rm -f $$files; }; \
  }
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libfreexl_la_DEPENDENCIES =
am_libfreexl_la_OBJECTS = freexl.lo freexl_xlsx.lo freexl_ods.lo
libfreexl_la_OBJECTS = $(am_libfreexl_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 
libfreexl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
................................................................................
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/freexl.Plo \
	./$(DEPDIR)/freexl_ods.Plo ./$(DEPDIR)/freexl_xlsx.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
................................................................................
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/headers -I$(top_srcdir)
lib_LTLIBRARIES = libfreexl.la 
libfreexl_la_SOURCES = freexl.c freexl_xlsx.c freexl_ods.c
libfreexl_la_LDFLAGS = -version-info 3:0:0 -no-undefined
libfreexl_la_LIBADD = -lm
MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
................................................................................
mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freexl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freexl_ods.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freexl_xlsx.Plo@am__quote@ # am--include-marker

$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

................................................................................
clean: clean-am

clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
	mostlyclean-am

distclean: distclean-am
		-rm -f ./$(DEPDIR)/freexl.Plo
	-rm -f ./$(DEPDIR)/freexl_ods.Plo
	-rm -f ./$(DEPDIR)/freexl_xlsx.Plo
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:
................................................................................

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f ./$(DEPDIR)/freexl.Plo
	-rm -f ./$(DEPDIR)/freexl_ods.Plo
	-rm -f ./$(DEPDIR)/freexl_xlsx.Plo
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

Changes to src/freexl.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
....
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
....
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
....
2791
2792
2793
2794
2795
2796
2797

2798
2799
2800
2801
2802
2803
2804
2805
....
3566
3567
3568
3569
3570
3571
3572

3573
3574
3575
3576
3577
3578
3579
3580
....
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097

4098


4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
....
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264

4265
4266
4267
4268
4269
4270
4271

4272
4273
4274
4275
4276
4277
4278

4279






4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290


4291
4292
4293
4294
4295


































































4296
4297
4298
4299

4300



4301
4302
4303
4304
4305
4306
4307
....
4499
4500
4501
4502
4503
4504
4505
4506













4507


















































































4508
4509
4510
4511
4512

4513



4514
4515
4516
4517
4518
4519
4520
....
4529
4530
4531
4532
4533
4534
4535
4536




















































4537
4538
4539
4540
4541
4542
4543

4544









4545
4546
4547
4548
4549
4550
4551
....
4562
4563
4564
4565
4566
4567
4568
4569
















































4570
4571
4572
4573
4574
4575
4576

4577









4578
4579
4580
4581
4582
4583
4584
....
4593
4594
4595
4596
4597
4598
4599
4600
















































4601
4602
4603
4604
4605
4606
4607

4608







4609
4610
4611
4612
4613
4614
4615
....
4626
4627
4628
4629
4630
4631
4632
4633
































4634
4635
4636
4637
4638

4639







4640
4641
4642
4643
4644
4645
4646
....
4653
4654
4655
4656
4657
4658
4659
4660



















4661
4662
4663
4664
4665

4666





4667
4668
4669
4670
4671
4672
4673
....
4680
4681
4682
4683
4684
4685
4686
4687
















































































































































































































































































































4688
4689
4690
4691
4692
4693

4694







4695
4696
4697
4698
4699
4700
4701
4702
4703
4704


4705
4706
4707
4708
4709
4710
4711
/* 
/ freexl.c
/
/ FreeXL implementation
/
/ version  1.0, 2011 July 26
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
................................................................................
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2011
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ Brad Hards
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
................................................................................
		if (!utf16)
		  {
		      /* 'stripped' UTF-16: requires padding */
		      unsigned int i;
		      for (i = 0; i < len; i++)
			{
			    if (p_string - workbook->record >=
				(int)workbook->record_size)
			      {
				  /* buffer overflow: it's a preasumable crafted file intended to crash FreeXL */
				  return FREEXL_CRAFTED_FILE;
			      }
			    *(utf16_buf + (utf16_off * 2) + (i * 2)) =
				*p_string;
			    p_string++;
................................................................................
		      /* already encoded as UTF-16 */
		      memcpy (utf16_buf + (utf16_off * 2), p_string, len * 2);
		      p_string += len * 2;
		  }

		/* skipping extra data (if any) */
		p_string += utf16_skip;
		if (p_string - workbook->record >= (int)workbook->record_size)
		    next_skip =
			(p_string - workbook->record) - workbook->record_size;
		else
		    next_skip = 0;

		/* converting text to UTF-8 */
		utf8_string =
................................................................................
	  /* skipping string data */
	  if (!utf16)
	      p_string += len;
	  else
	      p_string += len * 2;
	  /* skipping extra data (if any) */
	  p_string += workbook->shared_strings.current_utf16_skip;
	  if (p_string - workbook->record >= (int)workbook->record_size)
	      next_skip = (p_string - workbook->record) - workbook->record_size;
	  else
	      next_skip = 0;

	  *(workbook->shared_strings.utf8_strings + i_string) = utf8_string;
	  free (workbook->shared_strings.current_utf16_buf);
	  workbook->shared_strings.current_utf16_buf = NULL;
................................................................................
			  ret =
			      set_date_double_value (workbook, row, col,
						     workbook->biff_date_mode,
						     dbl_value);
		      else if (is_datetime)
			  ret =
			      set_datetime_double_value (workbook, row, col,

							 workbook->biff_date_mode,
							 dbl_value);
		      else if (is_time)
			  ret =
			      set_time_double_value (workbook, row, col,
						     dbl_value);
		      else
			  ret =
................................................................................
			  ret =
			      set_date_double_value (workbook, row, col,
						     workbook->biff_date_mode,
						     dbl_value);
		      else if (is_datetime)
			  ret =
			      set_datetime_double_value (workbook, row, col,

							 workbook->biff_date_mode,
							 dbl_value);
		      else if (is_time)
			  ret =
			      set_time_double_value (workbook, row, col,
						     dbl_value);
		      else
			  ret =
................................................................................
    word32.value = 1;
    if (word32.bytes[0] == 0)
	return 1;
    return 0;
}

static int
common_open (const char *path, const void **xls_handle, int magic)
{
/* opening and initializing the Workbook */
    biff_workbook *workbook;
    biff_sheet *p_sheet;
    fat_chain *chain = NULL;
    int errcode;
    int ret;
    int swap = check_little_endian_arch ();


    *xls_handle = NULL;


/* allocating the Workbook struct */
    workbook = alloc_workbook (magic);
    if (!workbook)
	return FREEXL_INSUFFICIENT_MEMORY;
    *xls_handle = workbook;

    workbook->xls = fopen (path, "rb");
    if (workbook->xls == NULL)
	return FREEXL_FILE_NOT_FOUND;

/*
 * the XLS file is internally structured as a FAT-like
................................................................................
    return FREEXL_OK;

  stop:
    if (chain)
	destroy_fat_chain (chain);
    if (workbook)
	destroy_workbook (workbook);
    *xls_handle = NULL;
    return errcode;
}

FREEXL_DECLARE int
freexl_open (const char *path, const void **xls_handle)
{
/* opening and initializing the Workbook */

    return common_open (path, xls_handle, FREEXL_MAGIC_START);
}

FREEXL_DECLARE int
freexl_open_info (const char *path, const void **xls_handle)
{
/* opening and initializing the Workbook (only for Info) */

    return common_open (path, xls_handle, FREEXL_MAGIC_INFO);
}

FREEXL_DECLARE int
freexl_close (const void *xls_handle)
{
/* attempting to destroy the Workbook */

    biff_workbook *workbook = (biff_workbook *) xls_handle;






    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
	return FREEXL_INVALID_HANDLE;

/* destroying the workbook */
    destroy_workbook (workbook);



    return FREEXL_OK;
}

FREEXL_DECLARE int


































































freexl_get_info (const void *xls_handle, unsigned short what,
		 unsigned int *info)
{
/* attempting to retrieve some info */

    biff_workbook *workbook = (biff_workbook *) xls_handle;



    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
	  else
	      *info = workbook->biff_xf_next_index;
	  return FREEXL_OK;
      };

    return FREEXL_INVALID_INFO_ARG;
}














FREEXL_DECLARE int


















































































freexl_get_FAT_entry (const void *xls_handle, unsigned int sector_index,
		      unsigned int *next_sector_index)
{
/* attempting to retrieve some FAT entry [by index] */
    fat_entry *entry;

    biff_workbook *workbook = (biff_workbook *) xls_handle;



    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!next_sector_index)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
    if (entry == NULL)
	return FREEXL_CFBF_ILLEGAL_FAT_ENTRY;
    *next_sector_index = entry->next_sector;

    return FREEXL_OK;

}





















































FREEXL_DECLARE int
freexl_get_worksheet_name (const void *xls_handle,
			   unsigned short worksheet_index, const char **string)
{
/* attempting to retrieve some Worksheet name [by index] */
    unsigned int count = 0;
    biff_sheet *worksheet;

    biff_workbook *workbook = (biff_workbook *) xls_handle;









    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!string)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_BIFF_ILLEGAL_SHEET_INDEX;
}

















































FREEXL_DECLARE int
freexl_select_active_worksheet (const void *xls_handle,
				unsigned short worksheet_index)
{
/* selecting the currently active worksheet [by index] */
    unsigned int count = 0;
    biff_sheet *worksheet;

    biff_workbook *workbook = (biff_workbook *) xls_handle;









    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
................................................................................
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_BIFF_ILLEGAL_SHEET_INDEX;
}

















































FREEXL_DECLARE int
freexl_get_active_worksheet (const void *xls_handle,
			     unsigned short *worksheet_index)
{
/* retrieving the currently active worksheet index */
    unsigned int count = 0;
    biff_sheet *worksheet;

    biff_workbook *workbook = (biff_workbook *) xls_handle;







    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!worksheet_index)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_BIFF_UNSELECTED_SHEET;
}

































FREEXL_DECLARE int
freexl_worksheet_dimensions (const void *xls_handle, unsigned int *rows,
			     unsigned short *columns)
{
/* dimensions: currently selected Worksheet */

    biff_workbook *workbook = (biff_workbook *) xls_handle;







    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!rows)
	return FREEXL_NULL_ARGUMENT;
    if (!columns)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
................................................................................
    if (workbook->active_sheet == NULL)
	return FREEXL_BIFF_UNSELECTED_SHEET;

    *rows = workbook->active_sheet->rows;
    *columns = workbook->active_sheet->columns;
    return FREEXL_OK;
}




















FREEXL_DECLARE int
freexl_get_SST_string (const void *xls_handle, unsigned short string_index,
		       const char **string)
{
/* attempting to retrieve some SST entry [by index] */

    biff_workbook *workbook = (biff_workbook *) xls_handle;





    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!string)
	return FREEXL_NULL_ARGUMENT;
    if (workbook->magic1 == FREEXL_MAGIC_START
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
................................................................................
    if (string_index < workbook->shared_strings.string_count)
      {
	  *string = *(workbook->shared_strings.utf8_strings + string_index);
	  return FREEXL_OK;
      }
    return FREEXL_BIFF_ILLEGAL_SST_INDEX;
}

















































































































































































































































































































FREEXL_DECLARE int
freexl_get_cell_value (const void *xls_handle, unsigned int row,
		       unsigned short column, FreeXL_CellValue * val)
{
/* attempting to fetch a cell value */
    biff_cell_value *p_cell;

    biff_workbook *workbook = (biff_workbook *) xls_handle;







    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!val)
	return FREEXL_NULL_ARGUMENT;
    if (workbook->magic1 == FREEXL_MAGIC_START
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
	return FREEXL_INVALID_HANDLE;



    if (row >= workbook->active_sheet->rows
	|| column >= workbook->active_sheet->columns)
	return FREEXL_ILLEGAL_CELL_ROW_COL;
    if (workbook->active_sheet->cell_values == NULL)
	return FREEXL_ILLEGAL_CELL_ROW_COL;

    p_cell =





|







 







|







 







|







 







|







 







|







 







>
|







 







>
|







 







|

|







>
|
>
>




|







 







|




|

|
>
|



|


>
|



|


>
|
>
>
>
>
>
>











>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<


>
|
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|




>
|
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|





>
|
>
>
>
>
>
>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|





>
|
>
>
>
>
>
>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|





>
|
>
>
>
>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|



>
|
>
>
>
>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|



>
|
>
>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|




>
|
>
>
>
>
>
>
>










>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
....
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
....
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
....
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
....
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
....
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
....
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378

4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
....
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
....
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
....
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
....
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
....
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
....
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
....
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
/* 
/ freexl.c
/
/ FreeXL implementation
/
/ version  2.0, 2021 June 10
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
................................................................................
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2011-2020
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ Brad Hards
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
................................................................................
		if (!utf16)
		  {
		      /* 'stripped' UTF-16: requires padding */
		      unsigned int i;
		      for (i = 0; i < len; i++)
			{
			    if (p_string - workbook->record >=
				(int) workbook->record_size)
			      {
				  /* buffer overflow: it's a preasumable crafted file intended to crash FreeXL */
				  return FREEXL_CRAFTED_FILE;
			      }
			    *(utf16_buf + (utf16_off * 2) + (i * 2)) =
				*p_string;
			    p_string++;
................................................................................
		      /* already encoded as UTF-16 */
		      memcpy (utf16_buf + (utf16_off * 2), p_string, len * 2);
		      p_string += len * 2;
		  }

		/* skipping extra data (if any) */
		p_string += utf16_skip;
		if (p_string - workbook->record >= (int) workbook->record_size)
		    next_skip =
			(p_string - workbook->record) - workbook->record_size;
		else
		    next_skip = 0;

		/* converting text to UTF-8 */
		utf8_string =
................................................................................
	  /* skipping string data */
	  if (!utf16)
	      p_string += len;
	  else
	      p_string += len * 2;
	  /* skipping extra data (if any) */
	  p_string += workbook->shared_strings.current_utf16_skip;
	  if (p_string - workbook->record >= (int) workbook->record_size)
	      next_skip = (p_string - workbook->record) - workbook->record_size;
	  else
	      next_skip = 0;

	  *(workbook->shared_strings.utf8_strings + i_string) = utf8_string;
	  free (workbook->shared_strings.current_utf16_buf);
	  workbook->shared_strings.current_utf16_buf = NULL;
................................................................................
			  ret =
			      set_date_double_value (workbook, row, col,
						     workbook->biff_date_mode,
						     dbl_value);
		      else if (is_datetime)
			  ret =
			      set_datetime_double_value (workbook, row, col,
							 workbook->
							 biff_date_mode,
							 dbl_value);
		      else if (is_time)
			  ret =
			      set_time_double_value (workbook, row, col,
						     dbl_value);
		      else
			  ret =
................................................................................
			  ret =
			      set_date_double_value (workbook, row, col,
						     workbook->biff_date_mode,
						     dbl_value);
		      else if (is_datetime)
			  ret =
			      set_datetime_double_value (workbook, row, col,
							 workbook->
							 biff_date_mode,
							 dbl_value);
		      else if (is_time)
			  ret =
			      set_time_double_value (workbook, row, col,
						     dbl_value);
		      else
			  ret =
................................................................................
    word32.value = 1;
    if (word32.bytes[0] == 0)
	return 1;
    return 0;
}

static int
common_open_xls (const char *path, freexl_handle ** handle, int magic)
{
/* opening and initializing the Workbook - XLS */
    biff_workbook *workbook;
    biff_sheet *p_sheet;
    fat_chain *chain = NULL;
    int errcode;
    int ret;
    int swap = check_little_endian_arch ();

    *handle = malloc (sizeof (freexl_handle));
    (*handle)->xls_handle = NULL;
    (*handle)->xlsx_handle = NULL;
    (*handle)->ods_handle = NULL;
/* allocating the Workbook struct */
    workbook = alloc_workbook (magic);
    if (!workbook)
	return FREEXL_INSUFFICIENT_MEMORY;
    (*handle)->xls_handle = workbook;

    workbook->xls = fopen (path, "rb");
    if (workbook->xls == NULL)
	return FREEXL_FILE_NOT_FOUND;

/*
 * the XLS file is internally structured as a FAT-like
................................................................................
    return FREEXL_OK;

  stop:
    if (chain)
	destroy_fat_chain (chain);
    if (workbook)
	destroy_workbook (workbook);
    (*handle)->xls_handle = NULL;
    return errcode;
}

FREEXL_DECLARE int
freexl_open (const char *path, const void **xl_handle)
{
/* opening and initializing the Workbook - XLS format expected */
    freexl_handle **handle = (freexl_handle **) xl_handle;
    return common_open_xls (path, handle, FREEXL_MAGIC_START);
}

FREEXL_DECLARE int
freexl_open_info (const char *path, const void **xl_handle)
{
/* opening and initializing the Workbook (only for Info) */
    freexl_handle **handle = (freexl_handle **) xl_handle;
    return common_open_xls (path, handle, FREEXL_MAGIC_INFO);
}

FREEXL_DECLARE int
freexl_close_xls (const void *xl_handle)
{
/* attempting to destroy the Workbook */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xls_handle == NULL)
	return FREEXL_INVALID_HANDLE;

    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
	return FREEXL_INVALID_HANDLE;

/* destroying the workbook */
    destroy_workbook (workbook);
/* destroying the handle */
    free (handle);

    return FREEXL_OK;
}

FREEXL_DECLARE int
freexl_close (const void *xl_handle)
{
/* attempting to destroy the Workbook */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    if (!handle)
	return FREEXL_NULL_HANDLE;

    if (handle->xls_handle != NULL)
      {
	  /* seems to be a XLS */
	  return freexl_close_xls (xl_handle);
      }

#ifndef OMIT_XMLDOC		/* only if XML support is enabled */
    if (handle->xlsx_handle != NULL)
      {
	  /* seems to be a XLSX */
	  return freexl_close_xlsx (xl_handle);
      }
    if (handle->ods_handle != NULL)
      {
	  /* seems to be an ODS */
	  return freexl_close_ods (xl_handle);
      }
#endif /* end conditional XML support */

    return FREEXL_INVALID_HANDLE;
}

static int
count_worksheets_xlsx (xlsx_workbook * wb)
{
/* counting how many Worksheets in a WorkBook - XLSX */
    int count = 0;
    xlsx_worksheet *ws;
    if (wb == NULL)
	return 0;

    ws = wb->first;
    while (ws != NULL)
      {
	  count++;
	  ws = ws->next;
      }
    return count;
}

static int
count_worksheets_ods (ods_workbook * wb)
{
/* counting how many Worksheets in a WorkBook - ODS */
    int count = 0;
    ods_worksheet *ws;
    if (wb == NULL)
	return 0;

    ws = wb->first;
    while (ws != NULL)
      {
	  count++;
	  ws = ws->next;
      }
    return count;
}

FREEXL_DECLARE int
freexl_get_info (const void *xl_handle, unsigned short what, unsigned int *info)

{
/* attempting to retrieve some info */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
	  else
	      *info = workbook->biff_xf_next_index;
	  return FREEXL_OK;
      };

    return FREEXL_INVALID_INFO_ARG;
}

static int
get_strings_xlsx (xlsx_workbook * workbook, unsigned int *info)
{
/* XLSX: attempting to retrieve the Single Strings count */
    if (!workbook)
	return FREEXL_INVALID_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;

    *info = workbook->n_strings;
    return FREEXL_OK;
}

FREEXL_DECLARE int
freexl_get_strings_count (const void *xl_handle, unsigned int *info)
{
/* attempting to retrieve the Single Strings count */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return get_strings_xlsx (handle->xlsx_handle, info);
    if (handle->ods_handle != NULL)
	return FREEXL_INVALID_HANDLE;
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
	return FREEXL_INVALID_HANDLE;

    *info = workbook->shared_strings.string_count;
    return FREEXL_OK;
}

static int
get_worksheets_xlsx (xlsx_workbook * workbook, unsigned int *info)
{
/* XLSX: attempting to retrieve the Worksheets count */
    if (!workbook)
	return FREEXL_INVALID_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;

    *info = count_worksheets_xlsx (workbook);
    return FREEXL_OK;
}

static int
get_worksheets_ods (ods_workbook * workbook, unsigned int *info)
{
/* ODS: attempting to retrieve the Worksheets count */
    if (!workbook)
	return FREEXL_INVALID_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;

    *info = count_worksheets_ods (workbook);
    return FREEXL_OK;
}

FREEXL_DECLARE int
freexl_get_worksheets_count (const void *xl_handle, unsigned int *info)
{
/* attempting to retrieve the Worksheets count */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return get_worksheets_xlsx (handle->xlsx_handle, info);
    if (handle->ods_handle != NULL)
	return get_worksheets_ods (handle->ods_handle, info);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!info)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
	return FREEXL_INVALID_HANDLE;

    *info = get_worksheet_count (workbook);
    return FREEXL_OK;
}

FREEXL_DECLARE int
freexl_get_FAT_entry (const void *xl_handle, unsigned int sector_index,
		      unsigned int *next_sector_index)
{
/* attempting to retrieve some FAT entry [by index] */
    fat_entry *entry;
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!next_sector_index)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
    if (entry == NULL)
	return FREEXL_CFBF_ILLEGAL_FAT_ENTRY;
    *next_sector_index = entry->next_sector;

    return FREEXL_OK;

}

static int
get_worksheet_name_xlsx (xlsx_workbook * workbook,
			 unsigned short worksheet_index, const char **string)
{
/* XLSX: attempting to retrieve some Worksheet name [by index] */
    unsigned int count = 0;
    xlsx_worksheet *worksheet;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!string)
	return FREEXL_NULL_ARGUMENT;

    worksheet = workbook->first;
    while (worksheet)
      {
	  if (count == worksheet_index)
	    {
		*string = worksheet->name;
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_XLSX_ILLEGAL_SHEET_INDEX;
}

static int
get_worksheet_name_ods (ods_workbook * workbook,
			unsigned short worksheet_index, const char **string)
{
/* ODS: attempting to retrieve some Worksheet name [by index] */
    unsigned int count = 0;
    ods_worksheet *worksheet;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!string)
	return FREEXL_NULL_ARGUMENT;

    worksheet = workbook->first;
    while (worksheet)
      {
	  if (count == worksheet_index)
	    {
		*string = worksheet->name;
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_ODS_ILLEGAL_SHEET_INDEX;
}

FREEXL_DECLARE int
freexl_get_worksheet_name (const void *xl_handle,
			   unsigned short worksheet_index, const char **string)
{
/* attempting to retrieve some Worksheet name [by index] */
    unsigned int count = 0;
    biff_sheet *worksheet;
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return get_worksheet_name_xlsx (handle->xlsx_handle, worksheet_index,
					string);
    if (handle->ods_handle != NULL)
	return get_worksheet_name_ods (handle->ods_handle, worksheet_index,
				       string);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!string)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_BIFF_ILLEGAL_SHEET_INDEX;
}

static int
select_active_worksheet_xlsx (xlsx_workbook * workbook,
			      unsigned short worksheet_index)
{
/* XLSX: selecting the currently active worksheet [by index] */
    unsigned int count = 0;
    xlsx_worksheet *worksheet;
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    worksheet = workbook->first;
    while (worksheet)
      {
	  if (count == worksheet_index)
	    {
		workbook->active_sheet = worksheet;
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_XLSX_ILLEGAL_SHEET_INDEX;
}

static int
select_active_worksheet_ods (ods_workbook * workbook,
			     unsigned short worksheet_index)
{
/* ODS: selecting the currently active worksheet [by index] */
    unsigned int count = 0;
    ods_worksheet *worksheet;
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    worksheet = workbook->first;
    while (worksheet)
      {
	  if (count == worksheet_index)
	    {
		workbook->active_sheet = worksheet;
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_ODS_ILLEGAL_SHEET_INDEX;
}

FREEXL_DECLARE int
freexl_select_active_worksheet (const void *xl_handle,
				unsigned short worksheet_index)
{
/* selecting the currently active worksheet [by index] */
    unsigned int count = 0;
    biff_sheet *worksheet;
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return select_active_worksheet_xlsx (handle->xlsx_handle,
					     worksheet_index);
    if (handle->ods_handle != NULL)
	return select_active_worksheet_ods (handle->ods_handle,
					    worksheet_index);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
................................................................................
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_BIFF_ILLEGAL_SHEET_INDEX;
}

static int
get_active_worksheet_xlsx (xlsx_workbook * workbook,
			   unsigned short *worksheet_index)
{
/* XLSX: retrieving the currently active worksheet index */
    unsigned int count = 0;
    xlsx_worksheet *worksheet;
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    worksheet = workbook->first;
    while (worksheet)
      {
	  if (workbook->active_sheet == worksheet)
	    {
		*worksheet_index = count;
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_XSLX_UNSELECTED_SHEET;
}

static int
get_active_worksheet_ods (ods_workbook * workbook,
			  unsigned short *worksheet_index)
{
/* ODS: retrieving the currently active worksheet index */
    unsigned int count = 0;
    ods_worksheet *worksheet;
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    worksheet = workbook->first;
    while (worksheet)
      {
	  if (workbook->active_sheet == worksheet)
	    {
		*worksheet_index = count;
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_ODS_UNSELECTED_SHEET;
}

FREEXL_DECLARE int
freexl_get_active_worksheet (const void *xl_handle,
			     unsigned short *worksheet_index)
{
/* retrieving the currently active worksheet index */
    unsigned int count = 0;
    biff_sheet *worksheet;
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return get_active_worksheet_xlsx (handle->xlsx_handle, worksheet_index);
    if (handle->ods_handle != NULL)
	return get_active_worksheet_ods (handle->ods_handle, worksheet_index);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!worksheet_index)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
	 || workbook->magic1 == FREEXL_MAGIC_START)
	&& workbook->magic2 == FREEXL_MAGIC_END)
................................................................................
		return FREEXL_OK;
	    }
	  count++;
	  worksheet = worksheet->next;
      }
    return FREEXL_BIFF_UNSELECTED_SHEET;
}

static int
worksheet_dimensions_xlsx (xlsx_workbook * workbook, unsigned int *rows,
			   unsigned short *columns)
{
/* XLSX: dimensions: currently selected Worksheet */
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    if (workbook->active_sheet == NULL)
	return FREEXL_XSLX_UNSELECTED_SHEET;

    *rows = workbook->active_sheet->max_row;
    *columns = workbook->active_sheet->max_cell + 1;
    return FREEXL_OK;
}

static int
worksheet_dimensions_ods (ods_workbook * workbook, unsigned int *rows,
			  unsigned short *columns)
{
/* ODS: dimensions: currently selected Worksheet */
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    if (workbook->active_sheet == NULL)
	return FREEXL_ODS_UNSELECTED_SHEET;

    *rows = workbook->active_sheet->max_row;
    *columns = workbook->active_sheet->max_cell + 1;
    return FREEXL_OK;
}

FREEXL_DECLARE int
freexl_worksheet_dimensions (const void *xl_handle, unsigned int *rows,
			     unsigned short *columns)
{
/* dimensions: currently selected Worksheet */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return worksheet_dimensions_xlsx (handle->xlsx_handle, rows, columns);
    if (handle->ods_handle != NULL)
	return worksheet_dimensions_ods (handle->ods_handle, rows, columns);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!rows)
	return FREEXL_NULL_ARGUMENT;
    if (!columns)
	return FREEXL_NULL_ARGUMENT;
    if ((workbook->magic1 == FREEXL_MAGIC_INFO
................................................................................
    if (workbook->active_sheet == NULL)
	return FREEXL_BIFF_UNSELECTED_SHEET;

    *rows = workbook->active_sheet->rows;
    *columns = workbook->active_sheet->columns;
    return FREEXL_OK;
}

static int
get_SST_string_xlsx (xlsx_workbook * workbook, unsigned short string_index,
		     const char **string)
{
/* XLSX: dimensions: attempting to retrieve some SST entry [by index] */
    if (!workbook)
	return FREEXL_NULL_HANDLE;

    *string = NULL;
    if (workbook->strings == NULL)
	return FREEXL_XLSX_INVALID_SST;
    if (string_index < workbook->n_strings)
      {
	  *string = *(workbook->strings + string_index);
	  return FREEXL_OK;
      }
    return FREEXL_XLSX_ILLEGAL_SST_INDEX;
}

FREEXL_DECLARE int
freexl_get_SST_string (const void *xl_handle, unsigned short string_index,
		       const char **string)
{
/* attempting to retrieve some SST entry [by index] */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return get_SST_string_xlsx (handle->xlsx_handle, string_index, string);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!string)
	return FREEXL_NULL_ARGUMENT;
    if (workbook->magic1 == FREEXL_MAGIC_START
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
................................................................................
    if (string_index < workbook->shared_strings.string_count)
      {
	  *string = *(workbook->shared_strings.utf8_strings + string_index);
	  return FREEXL_OK;
      }
    return FREEXL_BIFF_ILLEGAL_SST_INDEX;
}

static char *
find_datetime_xlsx (xlsx_workbook * workbook)
{
/* managing the DATETIME strings dynamic allocation - XLSX */
    xml_datetime *date;
    int r;
    if (workbook->first_date == NULL)
      {
	  /* inserting the first block into the list */
	  date = malloc (sizeof (xml_datetime));
	  for (r = 0; r < MAX_DATETIME_STR; r++)
	      date->datetime[r][0] = '\0';
	  date->next_str = 1;
	  date->next = NULL;
	  workbook->first_date = date;
	  workbook->last_date = date;
	  return date->datetime[0];
      }
    if (workbook->last_date->next_str >= 128)
      {
	  /* inserting a further block into the list */
	  date = malloc (sizeof (xml_datetime));
	  for (r = 0; r < MAX_DATETIME_STR; r++)
	      date->datetime[r][0] = '\0';
	  date->next_str = 1;
	  date->next = NULL;
	  workbook->last_date->next = date;
	  workbook->last_date = date;
	  return date->datetime[0];
      }
/* continuing to consume the current block */
    r = workbook->last_date->next_str;
    workbook->last_date->next_str += 1;
    return workbook->last_date->datetime[r];
}

static char *
find_datetime_ods (ods_workbook * workbook)
{
/* managing the DATETIME strings dynamic allocation - ODS */
    xml_datetime *date;
    int r;
    if (workbook->first_date == NULL)
      {
	  /* inserting the first block into the list */
	  date = malloc (sizeof (xml_datetime));
	  for (r = 0; r < MAX_DATETIME_STR; r++)
	      date->datetime[r][0] = '\0';
	  date->next_str = 1;
	  date->next = NULL;
	  workbook->first_date = date;
	  workbook->last_date = date;
	  return date->datetime[0];
      }
    if (workbook->last_date->next_str >= 128)
      {
	  /* inserting a further block into the list */
	  date = malloc (sizeof (xml_datetime));
	  for (r = 0; r < MAX_DATETIME_STR; r++)
	      date->datetime[r][0] = '\0';
	  date->next_str = 1;
	  date->next = NULL;
	  workbook->last_date->next = date;
	  workbook->last_date = date;
	  return date->datetime[0];
      }
/* continuing to consume the current block */
    r = workbook->last_date->next_str;
    workbook->last_date->next_str += 1;
    return workbook->last_date->datetime[r];
}

static int
get_cell_value_xlsx (xlsx_workbook * workbook, unsigned int row,
		     unsigned short column, FreeXL_CellValue * val)
{
/* attempting to fetch a cell value */
    xlsx_row *p_row;
    xlsx_cell *p_col;

    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (workbook->active_sheet == NULL)
	return FREEXL_XSLX_UNSELECTED_SHEET;
    if ((int) row >= workbook->active_sheet->max_row
	|| (int) column > workbook->active_sheet->max_cell)
	return FREEXL_ILLEGAL_CELL_ROW_COL;

    p_row = workbook->active_sheet->first;
    while (p_row != NULL)
      {
	  /* looping on Worksheet rows */
	  p_col = p_row->first;
	  while (p_col != NULL)
	    {
		p_col = p_col->next;
	    }
	  p_row = p_row->next;
      }

    p_row = workbook->active_sheet->first;
    while (p_row != NULL)
      {
	  /* looping on Worksheet rows */
	  if ((unsigned int) (p_row->row_no - 1) == row)
	    {
		p_col = p_row->first;
		while (p_col != NULL)
		  {
		      /* looping on row columns */
		      if ((unsigned int) (p_col->col_no) == column)
			{
			    if (p_col->assigned)
			      {
				  /* ok, found the requested Cell */
				  val->type = FREEXL_CELL_NULL;
				  if (p_col->is_datetime != XLSX_DATE_NONE)
				    {
					/* special case: DATE, TIME, DATETIME */
					char *datetime =
					    find_datetime_xlsx (workbook);
					double value;
					int count;
					int hh;
					int mm;
					int ss;
					int year = 1900;
					int month = 1;
					int day = 1;
					if (p_col->type == XLSX_INTEGER)
					  {
					      value = 0.0;
					      count = p_col->int_value;
					  }
					else if (p_col->type == XLSX_DOUBLE)
					  {
					      count =
						  (int)
						  floor (p_col->dbl_value);
					      value = p_col->dbl_value - count;
					  }
					else
					  {
					      value = 0.0;
					      count = 0;
					  }
					compute_time (&hh, &mm, &ss, value);
					compute_date (&year, &month, &day,
						      count);
					if (p_col->is_datetime ==
					    XLSX_DATE_SIMPLE)
					  {
					      sprintf (datetime,
						       "%04d-%02d-%02d", year,
						       month, day);
					      val->type = FREEXL_CELL_DATE;
					  }
					else if (p_col->is_datetime ==
						 XLSX_TIME_SIMPLE)
					  {
					      sprintf (datetime,
						       "%02d:%02d:%02d", hh, mm,
						       ss);
					      val->type = FREEXL_CELL_TIME;
					  }
					else
					  {
					      sprintf (datetime,
						       "%04d-%02d-%02d %02d:%02d:%02d",
						       year, month, day, hh, mm,
						       ss);
					      val->type = FREEXL_CELL_DATETIME;
					  }
					//val->value.text_value = NULL;
					val->value.text_value = datetime;
				    }
				  else
				    {
					/* ordinary values */
					if (p_col->type == XLSX_INTEGER)
					  {
					      val->type = FREEXL_CELL_INT;
					      val->value.int_value =
						  p_col->int_value;
					  }
					if (p_col->type == XLSX_DOUBLE)
					  {
					      val->type = FREEXL_CELL_DOUBLE;
					      val->value.double_value =
						  p_col->dbl_value;
					  }
					if (p_col->type == XLSX_STR_INDEX)
					  {
					      val->type = FREEXL_CELL_SST_TEXT;
					      val->value.text_value =
						  *(workbook->strings +
						    p_col->str_index);
					  }
				    }
				  return FREEXL_OK;
			      }
			}
		      p_col = p_col->next;
		  }
	    }
	  p_row = p_row->next;
      }

/* any undefined Cell is assumed to be NULL */
    val->type = FREEXL_CELL_NULL;
    return FREEXL_OK;
}

static void
adjust_ods_datetime (char *datetime)
{
/* adjusting an ODS Datatine value */
    char *p = datetime;
    if (datetime == NULL)
	return;
    while (*p != '\0')
      {
	  if (*p == 'T')
	      *p = ' ';
	  p++;
      }
}

static int
get_cell_value_ods (ods_workbook * workbook, unsigned int row,
		    unsigned short column, FreeXL_CellValue * val)
{
/* attempting to fetch a cell value */
    ods_row *p_row;
    ods_cell *p_col;

    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (workbook->active_sheet == NULL)
	return FREEXL_ODS_UNSELECTED_SHEET;
    if ((int) row >= workbook->active_sheet->max_row
	|| (int) column > workbook->active_sheet->max_cell)
	return FREEXL_ILLEGAL_CELL_ROW_COL;

    p_row = workbook->active_sheet->first;
    while (p_row != NULL)
      {
	  /* looping on Worksheet rows */
	  if ((unsigned int) (p_row->row_no - 1) == row)
	    {
		p_col = p_row->first;
		while (p_col != NULL)
		  {
		      /* looping on row columns */
		      if ((unsigned int) (p_col->col_no) == column)
			{
			    if (p_col->assigned)
			      {
				  /* ok, found the requested Cell */
				  val->type = FREEXL_CELL_NULL;
				  if (p_col->type == ODS_INTEGER
				      || p_col->type == ODS_BOOLEAN)
				    {
					val->type = FREEXL_CELL_INT;
					val->value.int_value = p_col->int_value;
				    }
				  if (p_col->type == ODS_FLOAT
				      || p_col->type == ODS_CURRENCY
				      || p_col->type == ODS_PERCENTAGE)
				    {
					val->type = FREEXL_CELL_DOUBLE;
					val->value.double_value =
					    p_col->dbl_value;
				    }
				  if (p_col->type == ODS_STRING
				      || p_col->type == ODS_TIME)
				    {
					val->type = FREEXL_CELL_TEXT;
					val->value.text_value =
					    p_col->txt_value;
				    }
				  if (p_col->type == ODS_DATE)
				    {
					char *datetime =
					    find_datetime_ods (workbook);
					strcpy (datetime, p_col->txt_value);
					adjust_ods_datetime (datetime);
					val->value.text_value = datetime;
					val->type = FREEXL_CELL_TEXT;
				    }
				  return FREEXL_OK;
			      }
			}
		      p_col = p_col->next;
		  }
	    }
	  p_row = p_row->next;
      }

/* any undefined Cell is assumed to be NULL */
    val->type = FREEXL_CELL_NULL;
    return FREEXL_OK;
}

FREEXL_DECLARE int
freexl_get_cell_value (const void *xl_handle, unsigned int row,
		       unsigned short column, FreeXL_CellValue * val)
{
/* attempting to fetch a cell value */
    biff_cell_value *p_cell;
    freexl_handle *handle = (freexl_handle *) xl_handle;
    biff_workbook *workbook;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle != NULL)
	return get_cell_value_xlsx (handle->xlsx_handle, row, column, val);
    if (handle->ods_handle != NULL)
	return get_cell_value_ods (handle->ods_handle, row, column, val);
    workbook = handle->xls_handle;
    if (!workbook)
	return FREEXL_NULL_HANDLE;
    if (!val)
	return FREEXL_NULL_ARGUMENT;
    if (workbook->magic1 == FREEXL_MAGIC_START
	&& workbook->magic2 == FREEXL_MAGIC_END)
	;
    else
	return FREEXL_INVALID_HANDLE;

    if (workbook->active_sheet == NULL)
	return FREEXL_XSLX_UNSELECTED_SHEET;
    if (row >= workbook->active_sheet->rows
	|| column >= workbook->active_sheet->columns)
	return FREEXL_ILLEGAL_CELL_ROW_COL;
    if (workbook->active_sheet->cell_values == NULL)
	return FREEXL_ILLEGAL_CELL_ROW_COL;

    p_cell =

Added src/freexl_ods.c.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
/* 
/ freexl_ods.c
/
/ FreeXL implementation (ODS support)
/
/ version  2.0, 2021 June 4
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>

#if defined(__MINGW32__) || defined(_WIN32)
#define LIBICONV_STATIC
#include <iconv.h>
#define LIBCHARSET_STATIC
#ifdef _MSC_VER
/* <localcharset.h> isn't supported on OSGeo4W */
/* applying a tricky workaround to fix this issue */
extern const char *locale_charset (void);
#else /* sane Windows - not OSGeo4W */
#include <localcharset.h>
#endif /* end localcharset */
#else /* not WINDOWS */
#if defined(__APPLE__) || defined(__ANDROID__)
#include <iconv.h>
#include <localcharset.h>
#else /* neither Mac OsX nor Android */
#include <iconv.h>
#include <langinfo.h>
#endif
#endif

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

#ifndef OMIT_XMLDOC		/* only if XML support is enabled */

#include <expat.h>

#include "freexl.h"
#include "freexl_internals.h"

#include <minizip/unzip.h>

#ifdef _WIN32
#define strcasecmp	_stricmp
#endif /* not WIN32 */

static void
xmlCharData (void *data, const XML_Char * s, int len)
{
/* parsing XML char data */
    ods_workbook *workbook = (ods_workbook *) data;
    if ((workbook->CharDataLen + len) > workbook->CharDataMax)
      {
	  /* we must increase the CharData buffer size */
	  void *new_buf;
	  int new_size = workbook->CharDataMax;
	  while (new_size < workbook->CharDataLen + len)
	      new_size += workbook->CharDataStep;
	  new_buf = realloc (workbook->CharData, new_size);
	  if (new_buf)
	    {
		workbook->CharData = new_buf;
		workbook->CharDataMax = new_size;
	    }
      }
    memcpy (workbook->CharData + workbook->CharDataLen, s, len);
    workbook->CharDataLen += len;
}

static ods_workbook *
alloc_workbook ()
{
/* allocating and initializing the Workbook struct */
    ods_workbook *wb = malloc (sizeof (ods_workbook));
    if (!wb)
	return NULL;
    wb->first = NULL;
    wb->last = NULL;
    wb->active_sheet = NULL;
    wb->first_date = NULL;
    wb->last_date = NULL;
    wb->error = 0;
    wb->ContentZipEntry = NULL;
    wb->CharDataStep = 65536;
    wb->CharDataMax = wb->CharDataStep;
    wb->CharData = malloc (wb->CharDataStep);
    wb->CharDataLen = 0;
    wb->ContentOk = 0;
    wb->NextWorksheetId = 0;
    return wb;
}

static void
destroy_row (ods_row * row)
{
/* memory cleanup - destroying a WorkSheet Row */
    ods_cell *col;
    ods_cell *col_n;
    if (row == NULL)
	return;

    col = row->first;
    while (col != NULL)
      {
	  col_n = col->next;
	  if (col->txt_value != NULL)
	      free (col->txt_value);
	  free (col);
	  col = col_n;
      }
    free (row);
}

static void
destroy_worksheet (ods_worksheet * ws)
{
/* memory cleanup - destroying a WorkSheet object */
    ods_row *row;
    ods_row *row_n;
    if (ws == NULL)
	return;

    row = ws->first;
    while (row != NULL)
      {
	  row_n = row->next;
	  destroy_row (row);
	  row = row_n;
      }
    if (ws->name != NULL)
	free (ws->name);
    free (ws);
}

static void
destroy_workbook (ods_workbook * wb)
{
/* memory cleanup - destroying a WorkBook object */
    ods_worksheet *ws;
    ods_worksheet *ws_n;
    xml_datetime *date;
    xml_datetime *date_n;
    if (wb == NULL)
	return;

    ws = wb->first;
    while (ws != NULL)
      {
	  ws_n = ws->next;
	  destroy_worksheet (ws);
	  ws = ws_n;
      }
    date = wb->first_date;
    while (date != NULL)
      {
	  date_n = date->next;
	  free (date);
	  date = date_n;
      }
    if (wb->ContentZipEntry != NULL)
	free (wb->ContentZipEntry);
    if (wb->CharData != NULL)
	free (wb->CharData);
    free (wb);
}

static void
do_add_cell (ods_worksheet * worksheet, int type, const char *value)
{
/* adding a Cell to the Worksheet Row */
    ods_row *row;
    ods_cell *cell;
    int len;
    int int_val;
    double dbl_val;

    row = worksheet->last;
    if (row == NULL)
	return;
    if (type == ODS_VOID)
      {
	  /* empty cell; just increasing the column number */
	  row->NextColNo += 1;
	  return;
      }

    cell = malloc (sizeof (ods_cell));
    cell->col_no = row->NextColNo;
    row->NextColNo += 1;
    cell->type = type;
    cell->assigned = 0;
    cell->txt_value = NULL;
    cell->next = NULL;
    if (value != NULL)
      {
	  switch (cell->type)
	    {
	    case ODS_DATE:
	    case ODS_TIME:
	    case ODS_STRING:
		len = strlen (value);
		cell->txt_value = malloc (len + 1);
		strcpy (cell->txt_value, value);
		cell->assigned = 1;
		break;
	    case ODS_FLOAT:
		int_val = atoi (value);
		dbl_val = atof (value);
		if (int_val == dbl_val)
		  {
		      cell->type = ODS_INTEGER;
		      cell->int_value = int_val;
		  }
		else
		    cell->dbl_value = atof (value);
		cell->assigned = 1;
		break;
	    case ODS_CURRENCY:
	    case ODS_PERCENTAGE:
		cell->dbl_value = atof (value);
		cell->assigned = 1;
		break;
	    case ODS_BOOLEAN:
		if (strcmp (value, "true") == 0)
		    cell->int_value = 1;
		else
		    cell->int_value = 0;
		cell->assigned = 0;
		break;
	    };
      }
    if (row->first == NULL)
	row->first = cell;
    if (row->last != NULL)
	row->last->next = cell;
    row->last = cell;

    if (cell->col_no > row->max_cell)
	row->max_cell = cell->col_no;
    if (cell->col_no > worksheet->max_cell)
	worksheet->max_cell = cell->col_no;
}

static void
do_add_row (ods_worksheet * worksheet)
{
/* adding a Row to the Worksheet */
    ods_row *row = malloc (sizeof (ods_row));
    row->row_no = worksheet->NextRowNo;
    worksheet->NextRowNo += 1;
    row->max_cell = -1;
    row->first = NULL;
    row->last = NULL;
    row->NextColNo = 0;
    row->next = NULL;
    if (worksheet->first == NULL)
	worksheet->first = row;
    if (worksheet->last != NULL)
	worksheet->last->next = row;
    worksheet->last = row;

    if (row->row_no > worksheet->max_row)
	worksheet->max_row = row->row_no;
}

static void
do_add_worksheet (ods_workbook * workbook, char *name)
{
/* adding a Worksheet to the Workbook */
    ods_worksheet *ws = malloc (sizeof (ods_worksheet));
    ws->id = workbook->NextWorksheetId;
    workbook->NextWorksheetId += 1;
    ws->name = name;
    ws->first = NULL;
    ws->last = NULL;
    ws->max_row = -1;
    ws->max_cell = -1;
    ws->RowOk = 0;
    ws->ColOk = 0;
    ws->CellValueOk = 0;
    ws->NextRowNo = 1;
    ws->next = NULL;
    if (workbook->first == NULL)
	workbook->first = ws;
    if (workbook->last != NULL)
	workbook->last->next = ws;
    workbook->last = ws;
}

static char *
setString (const char *entry)
{
/* permanently storing some relevant string */
    char *str = malloc (strlen (entry) + 1);
    strcpy (str, entry);
    return str;
}

static void
do_list_zipfile_dir (unzFile uf, ods_workbook * workbook)
{
/* parsing a Zipfile directory */
    unz_global_info64 gi;
    int ret;
    unsigned int i;
    ret = unzGetGlobalInfo64 (uf, &gi);
    if (ret != UNZ_OK)
      {
	  workbook->error = 1;
	  return;
      }

    for (i = 0; i < gi.number_entry; i++)
      {
	  /* looping on Zipfile entries */
	  char filename[256];
	  unz_file_info64 file_info;
	  ret =
	      unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0,
				       NULL, 0);
	  if (ret != UNZ_OK)
	    {
		workbook->error = 1;
		return;
	    }

	  if (strcasecmp (filename, "content.xml") == 0)
	    {
		/* found Workbook */
		workbook->ContentZipEntry = setString (filename);
	    }

	  if (i == gi.number_entry - 1)
	      break;
	  ret = unzGoToNextFile (uf);
	  if (ret != UNZ_OK)
	    {
		workbook->error = 1;
		return;
	    }
      }
}

static void
start_tag (void *data, const char *el, const char **attr)
{
/* some generic XML tag starts here */
    const char **attrib = attr;
    int count = 0;
    const char *k;
    const char *v;
    ods_workbook *workbook = (ods_workbook *) data;
    if (strcmp (el, "office:document-content") == 0)
	workbook->ContentOk = 1;
    if (strcmp (el, "office:body") == 0)
      {
	  if (workbook->ContentOk == 1)
	      workbook->ContentOk = 2;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "office:spreadsheet") == 0)
      {
	  if (workbook->ContentOk == 2)
	      workbook->ContentOk = 3;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "table:table") == 0)
      {
	  if (workbook->ContentOk == 3)
	    {
		char *name = NULL;
		workbook->ContentOk = 4;
		count = 0;
		while (*attrib != NULL)
		  {
		      if ((count % 2) == 0)
			  k = *attrib;
		      else
			{
			    v = *attrib;
			    if (strcmp (k, "table:name") == 0)
				name = setString (v);
			}
		      attrib++;
		      count++;
		  }
		if (name != NULL)
		    do_add_worksheet (workbook, name);
		else
		    workbook->error = 1;
	    }
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "table:table-row") == 0)
      {
	  ods_worksheet *worksheet = workbook->last;
	  if (worksheet == NULL)
	      workbook->error = 1;
	  else
	    {
		if (workbook->ContentOk == 4 && worksheet->RowOk == 0)
		  {
		      int i;
		      int repeated = 1;
		      count = 0;
		      while (*attrib != NULL)
			{
			    if ((count % 2) == 0)
				k = *attrib;
			    else
			      {
				  v = *attrib;
				  if (strcmp (k, "table:number-rows-repeated")
				      == 0)
				      repeated = atoi (v);
			      }
			    attrib++;
			    count++;
			}
		      if (repeated > 1024)
			{
			    /* exceeding repetitions; should be near the bottom of worksheet */
			    repeated = 1;
			}
		      for (i = 0; i < repeated; i++)
			  do_add_row (worksheet);
		      worksheet->RowOk = 1;
		  }
		else
		    workbook->error = 1;
	    }
      }
    if (strcmp (el, "table:table-cell") == 0
	|| strcmp (el, "table:covered-table-cell") == 0)
      {
	  ods_worksheet *worksheet = workbook->last;
	  if (worksheet == NULL)
	      workbook->error = 1;
	  else
	    {
		if (workbook->ContentOk == 4 && worksheet->RowOk == 1
		    && worksheet->ColOk == 0)
		  {
		      int i;
		      int repeated = 1;
		      int type = ODS_VOID;
		      char *xtype = NULL;
		      char *value = NULL;
		      count = 0;
		      while (*attrib != NULL)
			{
			    if ((count % 2) == 0)
				k = *attrib;
			    else
			      {
				  v = *attrib;
				  if (strcmp (k, "office:value-type") == 0)
				      xtype = setString (v);
				  if (strcmp (k, "office:value") == 0)
				      value = setString (v);
				  if (strcmp (k, "office:string-value") == 0)
				      value = setString (v);
				  if (strcmp (k, "office:boolean-value") == 0)
				      value = setString (v);
				  if (strcmp (k, "office:date-value") == 0)
				      value = setString (v);
				  if (strcmp (k, "office:time-value") == 0)
				      value = setString (v);
				  if (strcmp
				      (k, "table:number-columns-repeated") == 0)
				      repeated = atoi (v);
			      }
			    attrib++;
			    count++;
			}
		      if (xtype != NULL)
			{
			    if (strcmp (xtype, "string") == 0)
				type = ODS_STRING;
			    if (strcmp (xtype, "float") == 0)
				type = ODS_FLOAT;
			    if (strcmp (xtype, "currency") == 0)
				type = ODS_CURRENCY;
			    if (strcmp (xtype, "percentage") == 0)
				type = ODS_PERCENTAGE;
			    if (strcmp (xtype, "boolean") == 0)
				type = ODS_BOOLEAN;
			    if (strcmp (xtype, "date") == 0)
				type = ODS_DATE;
			    if (strcmp (xtype, "time") == 0)
				type = ODS_TIME;
			}
		      for (i = 0; i < repeated; i++)
			  do_add_cell (worksheet, type, value);
		      worksheet->ColOk = 1;
		      if (xtype != NULL)
			  free (xtype);
		      if (value != NULL)
			  free (value);
		  }
		else
		    workbook->error = 1;
	    }
      }
    if (strcmp (el, "text:p") == 0)
      {
	  ods_worksheet *worksheet = workbook->last;
	  if (worksheet == NULL)
	      workbook->error = 1;
	  else
	    {
		if (workbook->ContentOk == 4 && worksheet->RowOk == 1
		    && worksheet->ColOk == 1 && worksheet->CellValueOk == 0)
		    worksheet->CellValueOk = 1;
		else
		    workbook->error = 1;
	    }
      }
    *(workbook->CharData) = '\0';
    workbook->CharDataLen = 0;
}

static void
set_ods_cell_value (ods_worksheet * worksheet, const char *val)
{
/* assigning a value to the current cell */
    ods_row *row;
    ods_cell *cell;
    int len;

    if (worksheet == NULL)
	return;
    row = worksheet->last;
    if (row == NULL)
	return;
    cell = row->last;
    if (cell == NULL)
	return;
    if (cell->type != ODS_STRING)
	return;

    len = strlen (val);
    cell->txt_value = malloc (len + 1);
    strcpy (cell->txt_value, val);
    cell->assigned = 1;
}

static void
end_tag (void *data, const char *el)
{
/* some generic XML tag ends here */
    ods_workbook *workbook = (ods_workbook *) data;
    if (strcmp (el, "office:document-content") == 0)
      {
	  if (workbook->ContentOk == 1)
	      workbook->ContentOk = 0;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "office:body") == 0)
      {
	  if (workbook->ContentOk == 2)
	      workbook->ContentOk = 1;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "office:spreadsheet") == 0)
      {
	  if (workbook->ContentOk == 3)
	      workbook->ContentOk = 2;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "table:table") == 0)
      {
	  if (workbook->ContentOk == 4)
	      workbook->ContentOk = 3;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "table:table-row") == 0)
      {
	  ods_worksheet *worksheet = workbook->last;
	  if (worksheet == NULL)
	      workbook->error = 1;
	  else
	    {
		if (worksheet->RowOk == 1)
		    worksheet->RowOk = 0;
		else
		    workbook->error = 1;
	    }
      }
    if (strcmp (el, "table:table-cell") == 0
	|| strcmp (el, "table:covered-table-cell") == 0)
      {
	  ods_worksheet *worksheet = workbook->last;
	  if (worksheet == NULL)
	      workbook->error = 1;
	  else
	    {
		if (worksheet->ColOk == 1)
		    worksheet->ColOk = 0;
		else
		    workbook->error = 1;
	    }
      }
    if (strcmp (el, "text:p") == 0)
      {
	  ods_worksheet *worksheet = workbook->last;
	  if (worksheet == NULL)
	      workbook->error = 1;
	  else
	    {
		if (worksheet->CellValueOk == 1)
		  {
		      char *in;
		      *(workbook->CharData + workbook->CharDataLen) = '\0';
		      in = workbook->CharData;
		      set_ods_cell_value (worksheet, in);
		      worksheet->CellValueOk = 0;
		  }
		else
		    workbook->error = 1;
	    }
      }
}

static void
do_parse_ods_worksheets (ods_workbook * workbook, unsigned char *buf,
			 uint64_t size_buf)
{
/* parsing Content.xml */
    XML_Parser parser;
    int done = 0;

    parser = XML_ParserCreate (NULL);
    if (!parser)
      {
	  workbook->error = 1;
	  return;
      }

    XML_SetUserData (parser, workbook);
    XML_SetElementHandler (parser, start_tag, end_tag);
    XML_SetCharacterDataHandler (parser, xmlCharData);
    if (!XML_Parse (parser, (char *) buf, size_buf, done))
	workbook->error = 1;
    XML_ParserFree (parser);
}

static void
do_fetch_ods_worksheets (unzFile uf, ods_workbook * workbook)
{
/* uncompressing Content.xml */
    int err;
    char filename[256];
    unz_file_info64 file_info;
    uint64_t size_buf;
    unsigned char *buf = NULL;
    int is_open = 0;
    uint64_t rd_cnt;
    uint64_t unrd_cnt;

    err = unzLocateFile (uf, workbook->ContentZipEntry, 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    err =
	unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0, NULL,
				 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    size_buf = file_info.uncompressed_size;
    buf = malloc (size_buf);
    err = unzOpenCurrentFile (uf);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    is_open = 1;
    rd_cnt = 0;
    while (rd_cnt < size_buf)
      {
	  /* reading big chunks so to avoid large file issues */
	  uint32_t max = 1000000000;	/* max chunk size */
	  uint32_t len;
	  unrd_cnt = size_buf - rd_cnt;
	  if (unrd_cnt < max)
	      len = unrd_cnt;
	  else
	      len = max;
	  err = unzReadCurrentFile (uf, buf + rd_cnt, len);
	  if (err < 0)
	    {
		workbook->error = 1;
		goto skip;
	    }
	  rd_cnt += len;
      }

/* parsing Workbook.xml */
    do_parse_ods_worksheets (workbook, buf, size_buf);
    if (workbook->error == 0)
      {
	  /* adjusting all Worksheets */
	  ods_worksheet *ws = workbook->first;
	  while (ws != NULL)
	    {
		int max_col_no = -1;
		ods_row *row = ws->first;
		ws->max_row = -1;
		ws->max_cell = -1;
		while (row != NULL)
		  {
		      max_col_no = -1;
		      ods_cell *cell = row->first;
		      row->max_cell = -1;
		      while (cell != NULL)
			{
			    if (cell->assigned && cell->type != ODS_VOID)
			      {
				  if (cell->col_no > max_col_no)
				      max_col_no = cell->col_no;
			      }
			    cell = cell->next;
			}
		      if (max_col_no >= 0)
			{
			    row->max_cell = max_col_no;
			    if (row->row_no > ws->max_row)
				ws->max_row = row->row_no;
			    if (row->max_cell > ws->max_cell)
				ws->max_cell = row->max_cell;
			}
		      row = row->next;
		  }
		ws = ws->next;
	    }
      }

  skip:
    if (buf != NULL)
	free (buf);
    if (is_open)
	unzCloseCurrentFile (uf);
}

FREEXL_DECLARE int
freexl_open_ods (const char *path, const void **xl_handle)
{
/* opening and initializing the Workbook - XLSX format expected */
    ods_workbook *workbook;
    freexl_handle **handle = (freexl_handle **) xl_handle;
    unzFile uf = NULL;
    int retval = 0;

/* opening the ODS Spreadsheet as a Zipfile */
    uf = unzOpen64 (path);
    if (uf == NULL)
	return FREEXL_FILE_NOT_FOUND;

    retval = FREEXL_OK;
    *handle = malloc (sizeof (freexl_handle));
    (*handle)->xls_handle = NULL;
    (*handle)->xlsx_handle = NULL;
    (*handle)->ods_handle = NULL;

/* allocating the Workbook struct */
    workbook = alloc_workbook ();
    if (!workbook)
	return FREEXL_INSUFFICIENT_MEMORY;
/* parsing the Zipfile directory */
    do_list_zipfile_dir (uf, workbook);
    if (workbook->error)
      {
	  destroy_workbook (workbook);
	  retval = FREEXL_INVALID_XLSX;
	  goto stop;
      }

    if (workbook->ContentZipEntry != NULL)
      {
	  /* parsing Content.xml */
	  do_fetch_ods_worksheets (uf, workbook);
	  if (workbook->error)
	    {
		destroy_workbook (workbook);
		retval = FREEXL_INVALID_XLSX;
		goto stop;
	    }
      }
    (*handle)->ods_handle = workbook;

/* closing the Zipfile and quitting */
  stop:
    unzClose (uf);
    return retval;
}

FREEXL_DECLARE int
freexl_close_ods (const void *xl_handle)
{
/* attempting to destroy the Workbook */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->ods_handle == NULL)
	return FREEXL_INVALID_HANDLE;

/* destroying the workbook */
    destroy_workbook (handle->ods_handle);
/* destroying the handle */
    free (handle);

    return FREEXL_OK;
}

#endif /* end conditional XML support */

Added src/freexl_xlsx.c.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
/* 
/ freexl_xlsx.c
/
/ FreeXL implementation (XLSX support)
/
/ version  2.0, 2021 May 30
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>

#if defined(__MINGW32__) || defined(_WIN32)
#define LIBICONV_STATIC
#include <iconv.h>
#define LIBCHARSET_STATIC
#ifdef _MSC_VER
/* <localcharset.h> isn't supported on OSGeo4W */
/* applying a tricky workaround to fix this issue */
extern const char *locale_charset (void);
#else /* sane Windows - not OSGeo4W */
#include <localcharset.h>
#endif /* end localcharset */
#else /* not WINDOWS */
#if defined(__APPLE__) || defined(__ANDROID__)
#include <iconv.h>
#include <localcharset.h>
#else /* neither Mac OsX nor Android */
#include <iconv.h>
#include <langinfo.h>
#endif
#endif

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

#ifndef OMIT_XMLDOC		/* only if XML support is enabled */

#include <expat.h>

#include "freexl.h"
#include "freexl_internals.h"

#include <minizip/unzip.h>

#ifdef _WIN32
#define strcasecmp	_stricmp
#endif /* not WIN32 */

static void
xmlCharData (void *data, const XML_Char * s, int len)
{
/* parsing XML char data (Workbook) */
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if ((workbook->CharDataLen + len) > workbook->CharDataMax)
      {
	  /* we must increase the CharData buffer size */
	  void *new_buf;
	  int new_size = workbook->CharDataMax;
	  while (new_size < workbook->CharDataLen + len)
	      new_size += workbook->CharDataStep;
	  new_buf = realloc (workbook->CharData, new_size);
	  if (new_buf)
	    {
		workbook->CharData = new_buf;
		workbook->CharDataMax = new_size;
	    }
      }
    memcpy (workbook->CharData + workbook->CharDataLen, s, len);
    workbook->CharDataLen += len;
}

static void
xmlCharDataSheet (void *data, const XML_Char * s, int len)
{
/* parsing XML char data (Worksheet) */
    xlsx_worksheet *worksheet = (xlsx_worksheet *) data;
    if ((worksheet->CharDataLen + len) > worksheet->CharDataMax)
      {
	  /* we must increase the CharData buffer size */
	  void *new_buf;
	  int new_size = worksheet->CharDataMax;
	  while (new_size < worksheet->CharDataLen + len)
	      new_size += worksheet->CharDataStep;
	  new_buf = realloc (worksheet->CharData, new_size);
	  if (new_buf)
	    {
		worksheet->CharData = new_buf;
		worksheet->CharDataMax = new_size;
	    }
      }
    memcpy (worksheet->CharData + worksheet->CharDataLen, s, len);
    worksheet->CharDataLen += len;
}

static xlsx_workbook *
alloc_workbook ()
{
/* allocating and initializing the Workbook struct */
    xlsx_workbook *wb = malloc (sizeof (xlsx_workbook));
    if (!wb)
	return NULL;
    wb->first = NULL;
    wb->last = NULL;
    wb->active_sheet = NULL;
    wb->n_strings = 0;
    wb->xml_strings = 0;
    wb->strings = NULL;
    wb->n_formats = 0;
    wb->next_format = 0;
    wb->formats = NULL;
    wb->n_styles = 0;
    wb->next_style = 0;
    wb->styles = NULL;
    wb->first_date = NULL;
    wb->last_date = NULL;
    wb->error = 0;
    wb->SharedStringsZipEntry = NULL;
    wb->WorkbookZipEntry = NULL;
    wb->StylesZipEntry = NULL;
    wb->CharDataStep = 65536;
    wb->CharDataMax = wb->CharDataStep;
    wb->CharData = malloc (wb->CharDataStep);
    wb->CharDataLen = 0;
    wb->SharedStringsOk = 0;
    wb->WorksheetsOk = 0;
    wb->StylesOk = 0;
    wb->FormatsOk = 0;
    wb->CellStylesOk = 0;
    return wb;
}

static void
destroy_row (xlsx_row * row)
{
/* memory cleanup - destroying a WorkSheet Row */
    xlsx_cell *col;
    xlsx_cell *col_n;
    if (row == NULL)
	return;

    col = row->first;
    while (col != NULL)
      {
	  col_n = col->next;
	  free (col);
	  col = col_n;
      }
    free (row);
}

static void
destroy_worksheet (xlsx_worksheet * ws)
{
/* memory cleanup - destroying a WorkSheet object */
    xlsx_row *row;
    xlsx_row *row_n;
    if (ws == NULL)
	return;

    row = ws->first;
    while (row != NULL)
      {
	  row_n = row->next;
	  destroy_row (row);
	  row = row_n;
      }
    if (ws->name != NULL)
	free (ws->name);
    if (ws->CharData != NULL)
	free (ws->CharData);
    free (ws);
}

static void
destroy_workbook (xlsx_workbook * wb)
{
/* memory cleanup - destroying a WorkBook object */
    xlsx_worksheet *ws;
    xlsx_worksheet *ws_n;
    xml_datetime *date;
    xml_datetime *date_n;
    if (wb == NULL)
	return;

    ws = wb->first;
    while (ws != NULL)
      {
	  ws_n = ws->next;
	  destroy_worksheet (ws);
	  ws = ws_n;
      }
    date = wb->first_date;
    while (date != NULL)
      {
	  date_n = date->next;
	  free (date);
	  date = date_n;
      }
    if (wb->strings != NULL)
      {
	  int i;
	  for (i = 0; i < wb->n_strings; i++)
	    {
		char *str = *(wb->strings + i);
		if (str != NULL)
		    free (str);
	    }
	  free (wb->strings);
      }
    if (wb->formats != NULL)
	free (wb->formats);
    if (wb->styles != NULL)
	free (wb->styles);
    if (wb->SharedStringsZipEntry != NULL)
	free (wb->SharedStringsZipEntry);
    if (wb->WorkbookZipEntry != NULL)
	free (wb->WorkbookZipEntry);
    if (wb->StylesZipEntry != NULL)
	free (wb->StylesZipEntry);
    if (wb->CharData != NULL)
	free (wb->CharData);
    free (wb);
}

static char *
setString (const char *entry)
{
/* permanently storing some relevant string */
    char *str = malloc (strlen (entry) + 1);
    strcpy (str, entry);
    return str;
}

static void
do_list_zipfile_dir (unzFile uf, xlsx_workbook * workbook)
{
/* parsing a Zipfile directory */
    unz_global_info64 gi;
    int ret;
    unsigned int i;
    ret = unzGetGlobalInfo64 (uf, &gi);
    if (ret != UNZ_OK)
      {
	  workbook->error = 1;
	  return;
      }

    for (i = 0; i < gi.number_entry; i++)
      {
	  /* looping on Zipfile entries */
	  char filename[256];
	  unz_file_info64 file_info;
	  ret =
	      unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0,
				       NULL, 0);
	  if (ret != UNZ_OK)
	    {
		workbook->error = 1;
		return;
	    }

	  if (strcasecmp (filename, "xl/sharedStrings.xml") == 0)
	    {
		/* found SharedStrings */
		workbook->SharedStringsZipEntry = setString (filename);
	    }
	  if (strcasecmp (filename, "xl/workbook.xml") == 0)
	    {
		/* found Workbook */
		workbook->WorkbookZipEntry = setString (filename);
	    }
	  if (strcasecmp (filename, "xl/styles.xml") == 0)
	    {
		/* found Styles */
		workbook->StylesZipEntry = setString (filename);
	    }

	  if (i == gi.number_entry - 1)
	      break;
	  ret = unzGoToNextFile (uf);
	  if (ret != UNZ_OK)
	    {
		workbook->error = 1;
		return;
	    }
      }
}

static void
add_xlsx_row (xlsx_worksheet * worksheet, int row_no)
{
/* adding a row to a Worksheet */
    xlsx_row *row = malloc (sizeof (xlsx_row));
    row->row_no = row_no;
    row->max_cell = -1;
    row->first = NULL;
    row->last = NULL;
    row->next = NULL;

    if (worksheet->first == NULL)
	worksheet->first = row;
    if (worksheet->last != NULL)
	worksheet->last->next = row;
    worksheet->last = row;

    if (row_no > worksheet->max_row)
	worksheet->max_row = row_no;
}

static int
find_col_no (const char *sym)
{
/* attempting to get a column number */
    int i;
    int nro = 0;
    char x1 = 'A';
    char x2 = '\0';
    char dummy[8];
    char ref[128];

    strcpy (ref, sym);
    for (i = strlen (ref); i >= 0; i--)
      {
	  if (ref[i] >= '0' && ref[i] <= '9')
	      ref[i] = '\0';
      }
    if (strlen (ref) == 1 || strlen (ref) == 2)
	;
    else
	return -1;

    while (1)
      {
	  if (x2 == '\0')
	      sprintf (dummy, "%c", x1);
	  else
	      sprintf (dummy, "%c%c", x1, x2);
	  if (strcmp (dummy, ref) == 0)
	      return nro;
	  nro++;
	  if (x2 == '\0')
	    {
		if (x1 == 'Z')
		  {
		      x1 = 'A';
		      x2 = 'A';
		  }
		else
		    x1 += 1;
	    }
	  else
	    {
		if (x2 == 'Z' && x1 != 'Z')
		  {
		      x1 += 1;
		      x2 = 'A';
		  }
		else
		    x2 += 1;
	    }
      }
    return -1;
}

static void
add_xlsx_col (xlsx_worksheet * worksheet, int col_no, int type, int is_datetime)
{
/* adding a cell to a Worksheet row */
    xlsx_row *row;
    xlsx_cell *cell;

    row = worksheet->last;
    if (row == NULL)
      {
	  worksheet->error = 1;
	  return;
      }

    cell = malloc (sizeof (xlsx_cell));
    cell->col_no = col_no;
    cell->type = type;
    cell->is_datetime = is_datetime;
    cell->assigned = 0;
    cell->next = NULL;

    if (row->first == NULL)
	row->first = cell;
    if (row->last != NULL)
	row->last->next = cell;
    row->last = cell;

    if (col_no > row->max_cell)
	row->max_cell = col_no;
    if (col_no > worksheet->max_cell)
	worksheet->max_cell = col_no;
}

static int
xlsx_is_datetime (xlsx_workbook * workbook, int style)
{
/* checking for a DATETIME cell value */
    int is_datetime = 0;
    if (style >= 0 && style < workbook->n_styles)
      {
	  xlsx_style *stl = workbook->styles + style;
	  if (stl->formatRef != NULL)
	      is_datetime = stl->formatRef->is_datetime;
      }
    return is_datetime;
}

static void
sheet_start_tag (void *data, const char *el, const char **attr)
{
/* some generic XML tag starts here */
    const char **attrib = attr;
    int count = 0;
    const char *k;
    const char *v;
    xlsx_worksheet *worksheet = (xlsx_worksheet *) data;
    if (strcmp (el, "worksheet") == 0)
	worksheet->RowOk = 1;
    if (strcmp (el, "sheetData") == 0)
      {
	  if (worksheet->RowOk == 1)
	      worksheet->RowOk = 2;
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "row") == 0)
      {
	  if (worksheet->RowOk == 2)
	    {
		int row_no = -1;
		while (*attrib != NULL)
		  {
		      if ((count % 2) == 0)
			  k = *attrib;
		      else
			{
			    v = *attrib;
			    if (strcmp (k, "r") == 0)
				row_no = atoi (v);
			}
		      attrib++;
		      count++;
		  }
		if (row_no > 0)
		  {
		      add_xlsx_row (worksheet, row_no);
		      worksheet->RowOk = 3;
		  }
		else
		    worksheet->error = 1;
	    }
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "c") == 0)
      {
	  if (worksheet->RowOk == 3)
	    {
		const char *r = NULL;
		const char *t = NULL;
		int s = -1;
		int col_no = -1;
		int type = XLSX_NULL;
		while (*attrib != NULL)
		  {
		      if ((count % 2) == 0)
			  k = *attrib;
		      else
			{
			    v = *attrib;
			    if (strcmp (k, "r") == 0)
				r = v;
			    if (strcmp (k, "t") == 0)
				t = v;
			    if (strcmp (k, "s") == 0)
				s = atoi (v);
			}
		      attrib++;
		      count++;
		  }
		if (r != NULL)
		    col_no = find_col_no (r);
		if (col_no >= 0)
		  {
		      int is_datetime = XLSX_DATE_NONE;
		      if (s >= 0)
			  is_datetime = xlsx_is_datetime (worksheet->wbRef, s);
		      if (t != NULL)
			{
			    if (strcmp (t, "s") == 0)
				type = XLSX_STR_INDEX;
			    /*
			     * 'b' = BOOLEAN+
			     * 'd' = DATE ISO-8601
			     * 'e' = error
			     * 'inlineStr'
			     * 'n' = number
			     * 's' = shared string index
			     * 'str' = formula string
			     */
			    if (strcmp (t, "n") == 0)
				type = XLSX_INTEGER;
			}
		      add_xlsx_col (worksheet, col_no, type, is_datetime);
		      worksheet->ColOk = 1;
		  }
	    }
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "v") == 0)
      {
	  if (worksheet->ColOk == 1)
	      worksheet->CellValueOk = 1;
      }
    *(worksheet->CharData) = '\0';
    worksheet->CharDataLen = 0;
}

static void
set_xlsx_cell_value (xlsx_worksheet * worksheet, const char *val)
{
/* assigning a value to the current cell */
    xlsx_row *row;
    xlsx_cell *cell;

    if (worksheet == NULL)
	return;
    row = worksheet->last;
    if (row == NULL)
	return;
    cell = row->last;
    if (cell == NULL)
	return;

    if (cell->type == XLSX_STR_INDEX)
      {
	  cell->str_index = atoi (val);
	  cell->assigned = 1;
      }
    if (cell->type == XLSX_INTEGER)
      {
	  int i_val = atoi (val);
	  double d_val = atof (val);
	  if (i_val != d_val)
	    {
		cell->type = XLSX_DOUBLE;
		cell->dbl_value = d_val;
	    }
	  else
	      cell->int_value = i_val;
	  cell->assigned = 1;
      }
}

static void
sheet_end_tag (void *data, const char *el)
{
/* some generic XML tag ends here */
    xlsx_worksheet *worksheet = (xlsx_worksheet *) data;
    if (strcmp (el, "worksheet") == 0)
      {
	  if (worksheet->RowOk == 1)
	      worksheet->RowOk = 0;
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "sheetData") == 0)
      {
	  if (worksheet->RowOk == 2)
	      worksheet->RowOk = 1;
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "row") == 0)
      {
	  if (worksheet->RowOk == 3)
	      worksheet->RowOk = 2;
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "c") == 0)
      {
	  if (worksheet->ColOk == 1)
	      worksheet->ColOk = 0;
	  else
	      worksheet->error = 1;
      }
    if (strcmp (el, "v") == 0)
      {
	  if (worksheet->CellValueOk == 1)
	    {
		char *in;
		*(worksheet->CharData + worksheet->CharDataLen) = '\0';
		in = worksheet->CharData;
		set_xlsx_cell_value (worksheet, in);
		worksheet->CellValueOk = 0;
	    }
	  else
	      worksheet->error = 1;
      }
}

static void
do_parse_worksheet (xlsx_worksheet * worksheet, unsigned char *buf,
		    uint64_t size_buf)
{
/* parsing SheetN.xml */
    XML_Parser parser;
    int done = 0;

    parser = XML_ParserCreate (NULL);
    if (!parser)
      {
	  worksheet->error = 1;
	  return;
      }

    XML_SetUserData (parser, worksheet);
    XML_SetElementHandler (parser, sheet_start_tag, sheet_end_tag);
    XML_SetCharacterDataHandler (parser, xmlCharDataSheet);
    if (!XML_Parse (parser, (char *) buf, size_buf, done))
	worksheet->error = 1;
    XML_ParserFree (parser);
}

static void
do_fetch_worksheet (unzFile uf, xlsx_worksheet * worksheet)
{
/* uncompressing SheetN.xml */
    int err;
    char filename[256];
    unz_file_info64 file_info;
    uint64_t size_buf;
    unsigned char *buf = NULL;
    int is_open = 0;
    uint64_t rd_cnt;
    uint64_t unrd_cnt;
    char *zip_entry = malloc (strlen ("xl/worksheets/sheet123456789.xml") + 1);
    sprintf (zip_entry, "xl/worksheets/sheet%d.xml", worksheet->id);

    err = unzLocateFile (uf, zip_entry, 0);
    if (err != UNZ_OK)
      {
	  worksheet->error = 1;
	  goto skip;
      }
    err =
	unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0, NULL,
				 0);
    if (err != UNZ_OK)
      {
	  worksheet->error = 1;
	  goto skip;
      }
    size_buf = file_info.uncompressed_size;
    buf = malloc (size_buf);
    err = unzOpenCurrentFile (uf);
    if (err != UNZ_OK)
      {
	  worksheet->error = 1;
	  goto skip;
      }
    is_open = 1;
    rd_cnt = 0;
    while (rd_cnt < size_buf)
      {
	  /* reading big chunks so to avoid large file issues */
	  uint32_t max = 1000000000;	/* max chunk size */
	  uint32_t len;
	  unrd_cnt = size_buf - rd_cnt;
	  if (unrd_cnt < max)
	      len = unrd_cnt;
	  else
	      len = max;
	  err = unzReadCurrentFile (uf, buf + rd_cnt, len);
	  if (err < 0)
	    {
		worksheet->error = 1;
		goto skip;
	    }
	  rd_cnt += len;
      }

/* parsing SheetN.xml */
    do_parse_worksheet (worksheet, buf, size_buf);

  skip:
    if (zip_entry != NULL)
	free (zip_entry);
    if (buf != NULL)
	free (buf);
    if (is_open)
	unzCloseCurrentFile (uf);
}

static void
do_add_worksheet (xlsx_workbook * workbook, int id, char *name)
{
/* adding a Worksheet to the Workbook */
    xlsx_worksheet *ws = malloc (sizeof (xlsx_worksheet));
    ws->id = id;
    ws->name = name;
    ws->first = NULL;
    ws->last = NULL;
    ws->max_row = -1;
    ws->max_cell = -1;
    ws->error = 0;
    ws->CharDataStep = 65536;
    ws->CharDataMax = ws->CharDataStep;
    ws->CharData = malloc (ws->CharDataStep);
    ws->CharDataLen = 0;
    ws->RowOk = 0;
    ws->ColOk = 0;
    ws->wbRef = workbook;
    ws->next = NULL;
    if (workbook->first == NULL)
	workbook->first = ws;
    if (workbook->last != NULL)
	workbook->last->next = ws;
    workbook->last = ws;
}

static void
worksheets_start_tag (void *data, const char *el, const char **attr)
{
/* some generic XML tag starts here */
    const char **attrib = attr;
    int count = 0;
    const char *k;
    const char *v;
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if (strcmp (el, "workbook") == 0)
	workbook->WorksheetsOk = 1;
    if (strcmp (el, "sheets") == 0)
      {
	  if (workbook->WorksheetsOk == 1)
	      workbook->WorksheetsOk = 2;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "sheet") == 0)
      {
	  int id = -1;
	  char *name = NULL;
	  if (workbook->WorksheetsOk != 2)
	    {
		workbook->error = 1;
		return;
	    }
	  while (*attrib != NULL)
	    {
		if ((count % 2) == 0)
		    k = *attrib;
		else
		  {
		      v = *attrib;
		      if (strcmp (k, "sheetId") == 0)
			  id = atoi (v);
		      if (strcmp (k, "name") == 0)
			  name = setString (v);
		  }
		attrib++;
		count++;
	    }
	  if (id > 0 && name != NULL)
	      do_add_worksheet (workbook, id, name);
	  else
	    {
		if (name != NULL)
		    free (name);
		workbook->error = 1;
	    }
      }
}

static void
worksheets_end_tag (void *data, const char *el)
{
/* some generic XML tag ends here */
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if (strcmp (el, "workbook") == 0)
      {
	  if (workbook->WorksheetsOk == 1)
	      workbook->WorksheetsOk = 0;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "sheets") == 0)
      {
	  if (workbook->WorksheetsOk == 2)
	      workbook->WorksheetsOk = 1;
	  else
	      workbook->error = 1;
      }
}

static void
do_parse_xlsx_worksheets (xlsx_workbook * workbook, unsigned char *buf,
			  uint64_t size_buf)
{
/* parsing Workbook.xml */
    XML_Parser parser;
    int done = 0;

    parser = XML_ParserCreate (NULL);
    if (!parser)
      {
	  workbook->error = 1;
	  return;
      }

    XML_SetUserData (parser, workbook);
    XML_SetElementHandler (parser, worksheets_start_tag, worksheets_end_tag);
    XML_SetCharacterDataHandler (parser, xmlCharData);
    if (!XML_Parse (parser, (char *) buf, size_buf, done))
	workbook->error = 1;
    XML_ParserFree (parser);
}

static void
do_fetch_xlsx_worksheets (unzFile uf, xlsx_workbook * workbook)
{
/* uncompressing Workbook.xml */
    int err;
    char filename[256];
    unz_file_info64 file_info;
    uint64_t size_buf;
    unsigned char *buf = NULL;
    int is_open = 0;
    uint64_t rd_cnt;
    uint64_t unrd_cnt;

    err = unzLocateFile (uf, workbook->WorkbookZipEntry, 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    err =
	unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0, NULL,
				 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    size_buf = file_info.uncompressed_size;
    buf = malloc (size_buf);
    err = unzOpenCurrentFile (uf);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    is_open = 1;
    rd_cnt = 0;
    while (rd_cnt < size_buf)
      {
	  /* reading big chunks so to avoid large file issues */
	  uint32_t max = 1000000000;	/* max chunk size */
	  uint32_t len;
	  unrd_cnt = size_buf - rd_cnt;
	  if (unrd_cnt < max)
	      len = unrd_cnt;
	  else
	      len = max;
	  err = unzReadCurrentFile (uf, buf + rd_cnt, len);
	  if (err < 0)
	    {
		workbook->error = 1;
		goto skip;
	    }
	  rd_cnt += len;
      }

/* parsing Workbook.xml */
    do_parse_xlsx_worksheets (workbook, buf, size_buf);

  skip:
    if (buf != NULL)
	free (buf);
    if (is_open)
	unzCloseCurrentFile (uf);
}

static void
shared_strings_start_tag (void *data, const char *el, const char **attr)
{
/* some generic XML tag starts here */
    const char **attrib = attr;
    int count = 0;
    const char *k;
    const char *v;
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if (strcmp (el, "sst") == 0)
      {
	  while (*attrib != NULL)
	    {
		if ((count % 2) == 0)
		    k = *attrib;
		else
		  {
		      v = *attrib;
		      if (strcmp (k, "uniqueCount") == 0)
			  workbook->n_strings = atoi (v);
		  }
		attrib++;
		count++;
	    }
	  if (workbook->n_strings > 0)
	    {
		/* allocating the SharedStrings array */
		int i;
		workbook->strings =
		    malloc (sizeof (char *) * workbook->n_strings);
		for (i = 0; i < workbook->n_strings; i++)
		    *(workbook->strings + i) = NULL;
	    }
	  workbook->SharedStringsOk = 1;
      }
    *(workbook->CharData) = '\0';
    workbook->CharDataLen = 0;
}

static void
shared_strings_end_tag (void *data, const char *el)
{
/* some generic XML tag ends here */
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if (strcmp (el, "sst") == 0)
      {
	  if (workbook->n_strings != workbook->xml_strings)
	      workbook->error = 1;
	  workbook->SharedStringsOk = 0;
      }
    if (strcmp (el, "si") == 0)
      {
	  if (workbook->SharedStringsOk == 0)
	    {
		workbook->error = 1;
		return;
	    }
	  if (workbook->xml_strings < workbook->n_strings)
	    {
		char *in;
		*(workbook->CharData + workbook->CharDataLen) = '\0';
		in = workbook->CharData;
		*(workbook->strings + workbook->xml_strings) =
		    malloc (strlen (in) + 1);
		strcpy (*(workbook->strings + workbook->xml_strings), in);
		workbook->xml_strings += 1;
	    }
	  else
	      workbook->error = 1;
      }
}

static void
do_parse_xlsx_shared_strings (xlsx_workbook * workbook, unsigned char *buf,
			      uint64_t size_buf)
{
/* parsing SharedStrings.xml */
    XML_Parser parser;
    int done = 0;

    parser = XML_ParserCreate (NULL);
    if (!parser)
      {
	  workbook->error = 1;
	  return;
      }

    XML_SetUserData (parser, workbook);
    XML_SetElementHandler (parser, shared_strings_start_tag,
			   shared_strings_end_tag);
    XML_SetCharacterDataHandler (parser, xmlCharData);
    if (!XML_Parse (parser, (char *) buf, size_buf, done))
	workbook->error = 1;
    XML_ParserFree (parser);
}

static void
do_fetch_xlsx_shared_strings (unzFile uf, xlsx_workbook * workbook)
{
/* uncompressing SharedStrings.xml */
    int err;
    char filename[256];
    unz_file_info64 file_info;
    uint64_t size_buf;
    unsigned char *buf = NULL;
    int is_open = 0;
    uint64_t rd_cnt;
    uint64_t unrd_cnt;

    err = unzLocateFile (uf, workbook->SharedStringsZipEntry, 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    err =
	unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0, NULL,
				 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    size_buf = file_info.uncompressed_size;
    buf = malloc (size_buf);
    err = unzOpenCurrentFile (uf);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    is_open = 1;
    rd_cnt = 0;
    while (rd_cnt < size_buf)
      {
	  /* reading big chunks so to avoid large file issues */
	  uint32_t max = 1000000000;	/* max chunk size */
	  uint32_t len;
	  unrd_cnt = size_buf - rd_cnt;
	  if (unrd_cnt < max)
	      len = unrd_cnt;
	  else
	      len = max;
	  err = unzReadCurrentFile (uf, buf + rd_cnt, len);
	  if (err < 0)
	    {
		workbook->error = 1;
		goto skip;
	    }
	  rd_cnt += len;
      }

/* parsing SharedStrings.xml */
    do_parse_xlsx_shared_strings (workbook, buf, size_buf);

  skip:
    if (buf != NULL)
	free (buf);
    if (is_open)
	unzCloseCurrentFile (uf);
}

static int
parse_xlsx_format (const char *code)
{
/* parsing a XLSX format string */
    int is_date = 0;
    int is_time = 0;
    int i;
    int len = strlen (code);
    for (i = 0; i < len; i++)
      {
	  if (code[i] == 'd' || code[i] == 'm' || code[i] == 'y')
	      is_date = 1;
	  if (code[i] == 'h' || code[i] == 's')
	      is_time = 1;
      }
    if (is_date && is_time)
	return XLSX_DATE_AND_TIME;
    if (is_date)
	return XLSX_DATE_SIMPLE;
    if (is_time)
	return XLSX_TIME_SIMPLE;
    return XLSX_DATE_NONE;
}

static xlsx_format *
find_xlsx_format (xlsx_workbook * workbook, int id)
{
/* searching for a given Format */
    int i;
    for (i = 0; i < workbook->n_formats; i++)
      {
	  xlsx_format *fmt = workbook->formats + i;
	  if (fmt->fmtId == id)
	      return fmt;
      }
    return NULL;
}

static void
styles_start_tag (void *data, const char *el, const char **attr)
{
/* some generic XML tag starts here */
    const char **attrib = attr;
    int count = 0;
    const char *k;
    const char *v;
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if (strcmp (el, "styleSheet") == 0)
	workbook->StylesOk = 1;
    if (strcmp (el, "numFmts") == 0)
      {
	  if (workbook->StylesOk == 1 && workbook->FormatsOk == 0)
	    {
		while (*attrib != NULL)
		  {
		      if ((count % 2) == 0)
			  k = *attrib;
		      else
			{
			    v = *attrib;
			    if (strcmp (k, "count") == 0)
				workbook->n_formats = atoi (v);
			}
		      attrib++;
		      count++;
		  }
		if (workbook->n_formats > 0)
		  {
		      /* allocating the Formats array */
		      int i;
		      workbook->formats =
			  malloc (sizeof (xlsx_format) * workbook->n_formats);
		      for (i = 0; i < workbook->n_formats; i++)
			{
			    xlsx_format *fmt = workbook->formats + i;
			    fmt->fmtId = -1;
			    fmt->is_datetime = 0;
			}
		  }
		workbook->next_format = 0;
		workbook->FormatsOk = 1;
	    }
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "numFmt") == 0)
      {
	  if (workbook->StylesOk == 1 && workbook->FormatsOk == 1
	      && workbook->next_format >= 0
	      && workbook->next_format < workbook->n_formats)
	    {
		int id = -1;
		const char *code;
		while (*attrib != NULL)
		  {
		      if ((count % 2) == 0)
			  k = *attrib;
		      else
			{
			    v = *attrib;
			    if (strcmp (k, "numFmtId") == 0)
				id = atoi (v);
			    if (strcmp (k, "formatCode") == 0)
				code = v;
			}
		      attrib++;
		      count++;
		  }
		if (id >= 0 && code != NULL)
		  {
		      xlsx_format *fmt =
			  workbook->formats + workbook->next_format;
		      fmt->fmtId = id;
		      fmt->is_datetime = parse_xlsx_format (code);
		  }
		workbook->next_format += 1;
	    }
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "cellXfs") == 0)
      {
	  if (workbook->StylesOk == 1 && workbook->CellStylesOk == 0)
	    {
		while (*attrib != NULL)
		  {
		      if ((count % 2) == 0)
			  k = *attrib;
		      else
			{
			    v = *attrib;
			    if (strcmp (k, "count") == 0)
				workbook->n_styles = atoi (v);
			}
		      attrib++;
		      count++;
		  }
		if (workbook->n_styles > 0)
		  {
		      /* allocating the Styles array */
		      int i;
		      workbook->styles =
			  malloc (sizeof (xlsx_style) * workbook->n_styles);
		      for (i = 0; i < workbook->n_styles; i++)
			{
			    xlsx_style *stl = workbook->styles + i;
			    stl->stlId = -1;
			    stl->formatRef = NULL;
			}
		  }
		workbook->next_style = 0;
		workbook->CellStylesOk = 1;
	    }
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "xf") == 0)
      {
	  if (workbook->StylesOk == 1 && workbook->CellStylesOk == 1)
	    {
		if (workbook->next_style >= 0
		    && workbook->next_style < workbook->n_styles)
		  {
		      int id = -1;
		      while (*attrib != NULL)
			{
			    if ((count % 2) == 0)
				k = *attrib;
			    else
			      {
				  v = *attrib;
				  if (strcmp (k, "numFmtId") == 0)
				      id = atoi (v);
			      }
			    attrib++;
			    count++;
			}
		      if (id >= 0)
			{
			    xlsx_style *stl =
				workbook->styles + workbook->next_style;
			    stl->stlId = id;
			    stl->formatRef = find_xlsx_format (workbook, id);
			}
		      workbook->next_style += 1;
		  }
		else
		    workbook->error = 1;
	    }
      }
}

static void
styles_end_tag (void *data, const char *el)
{
/* some generic XML tag ends here */
    xlsx_workbook *workbook = (xlsx_workbook *) data;
    if (strcmp (el, "styleSheet") == 0)
      {
	  if (workbook->StylesOk == 1)
	      workbook->StylesOk = 0;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "numFmts") == 0)
      {
	  if (workbook->FormatsOk == 1)
	      workbook->FormatsOk = 0;
	  else
	      workbook->error = 1;
      }
    if (strcmp (el, "cellXfs") == 0)
      {
	  if (workbook->CellStylesOk == 1)
	      workbook->CellStylesOk = 0;
	  else
	      workbook->error = 1;
      }
}

static void
do_parse_xlsx_styles (xlsx_workbook * workbook, unsigned char *buf,
		      uint64_t size_buf)
{
/* parsing Styles.xml */
    XML_Parser parser;
    int done = 0;

    parser = XML_ParserCreate (NULL);
    if (!parser)
      {
	  workbook->error = 1;
	  return;
      }

    XML_SetUserData (parser, workbook);
    XML_SetElementHandler (parser, styles_start_tag, styles_end_tag);
    XML_SetCharacterDataHandler (parser, xmlCharData);
    if (!XML_Parse (parser, (char *) buf, size_buf, done))
	workbook->error = 1;
    XML_ParserFree (parser);
}

static void
do_fetch_xlsx_styles (unzFile uf, xlsx_workbook * workbook)
{
/* uncompressing Styles.xml */
    int err;
    char filename[256];
    unz_file_info64 file_info;
    uint64_t size_buf;
    unsigned char *buf = NULL;
    int is_open = 0;
    uint64_t rd_cnt;
    uint64_t unrd_cnt;

    err = unzLocateFile (uf, workbook->StylesZipEntry, 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    err =
	unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0, NULL,
				 0);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    size_buf = file_info.uncompressed_size;
    buf = malloc (size_buf);
    err = unzOpenCurrentFile (uf);
    if (err != UNZ_OK)
      {
	  workbook->error = 1;
	  goto skip;
      }
    is_open = 1;
    rd_cnt = 0;
    while (rd_cnt < size_buf)
      {
	  /* reading big chunks so to avoid large file issues */
	  uint32_t max = 1000000000;	/* max chunk size */
	  uint32_t len;
	  unrd_cnt = size_buf - rd_cnt;
	  if (unrd_cnt < max)
	      len = unrd_cnt;
	  else
	      len = max;
	  err = unzReadCurrentFile (uf, buf + rd_cnt, len);
	  if (err < 0)
	    {
		workbook->error = 1;
		goto skip;
	    }
	  rd_cnt += len;
      }

/* parsing Syles.xml */
    do_parse_xlsx_styles (workbook, buf, size_buf);

  skip:
    if (buf != NULL)
	free (buf);
    if (is_open)
	unzCloseCurrentFile (uf);
}

FREEXL_DECLARE int
freexl_open_xlsx (const char *path, const void **xl_handle)
{
/* opening and initializing the Workbook - XLSX format expected */
    xlsx_workbook *workbook;
    xlsx_worksheet *worksheet;
    freexl_handle **handle = (freexl_handle **) xl_handle;
    unzFile uf = NULL;
    int retval = 0;

/* opening the XLSX Spreadsheet as a Zipfile */
    uf = unzOpen64 (path);
    if (uf == NULL)
	return FREEXL_FILE_NOT_FOUND;

    retval = FREEXL_OK;
    *handle = malloc (sizeof (freexl_handle));
    (*handle)->xls_handle = NULL;
    (*handle)->xlsx_handle = NULL;
    (*handle)->ods_handle = NULL;

/* allocating the Workbook struct */
    workbook = alloc_workbook ();
    if (!workbook)
	return FREEXL_INSUFFICIENT_MEMORY;
/* parsing the Zipfile directory */
    do_list_zipfile_dir (uf, workbook);
    if (workbook->error)
      {
	  destroy_workbook (workbook);
	  retval = FREEXL_INVALID_XLSX;
	  goto stop;
      }

    if (workbook->SharedStringsZipEntry != NULL)
      {
	  /* parsing SharedStrings.xml */
	  do_fetch_xlsx_shared_strings (uf, workbook);
	  if (workbook->error)
	    {
		destroy_workbook (workbook);
		retval = FREEXL_INVALID_XLSX;
		goto stop;
	    }
      }
    if (workbook->StylesZipEntry != NULL)
      {
	  /* parsing Styles.xml */
	  do_fetch_xlsx_styles (uf, workbook);
	  if (workbook->error)
	    {
		destroy_workbook (workbook);
		retval = FREEXL_INVALID_XLSX;
		goto stop;
	    }
      }
    if (workbook->WorkbookZipEntry != NULL)
      {
	  /* parsing Workbook.xml */
	  do_fetch_xlsx_worksheets (uf, workbook);
	  if (workbook->error)
	    {
		destroy_workbook (workbook);
		retval = FREEXL_INVALID_XLSX;
		goto stop;
	    }
      }
    worksheet = workbook->first;
    while (worksheet != NULL)
      {
	  /* parsing all Worksheets */
	  do_fetch_worksheet (uf, worksheet);
	  if (worksheet->error)
	    {
		destroy_workbook (workbook);
		retval = FREEXL_INVALID_XLSX;
		goto stop;
	    }
	  worksheet = worksheet->next;
      }
    if (workbook->error == 0)
      {
	  /* adjusting all Worksheets */
	  xlsx_worksheet *ws = workbook->first;
	  while (ws != NULL)
	    {
		int max_col_no = -1;
		xlsx_row *row = ws->first;
		ws->max_row = -1;
		ws->max_cell = -1;
		while (row != NULL)
		  {
		      max_col_no = -1;
		      xlsx_cell *cell = row->first;
		      row->max_cell = -1;
		      while (cell != NULL)
			{
			    if (cell->assigned && cell->type != XLSX_NULL)
			      {
				  if (cell->col_no > max_col_no)
				      max_col_no = cell->col_no;
			      }
			    cell = cell->next;
			}
		      if (max_col_no >= 0)
			{
			    row->max_cell = max_col_no;
			    if (row->row_no > ws->max_row)
				ws->max_row = row->row_no;
			    if (row->max_cell > ws->max_cell)
				ws->max_cell = row->max_cell;
			}
		      row = row->next;
		  }
		ws = ws->next;
	    }
      }
    (*handle)->xlsx_handle = workbook;

/* closing the Zipfile and quitting */
  stop:
    unzClose (uf);
    return retval;
}

FREEXL_DECLARE int
freexl_close_xlsx (const void *xl_handle)
{
/* attempting to destroy the Workbook */
    freexl_handle *handle = (freexl_handle *) xl_handle;
    if (!handle)
	return FREEXL_NULL_HANDLE;
    if (handle->xlsx_handle == NULL)
	return FREEXL_INVALID_HANDLE;

/* destroying the workbook */
    destroy_workbook (handle->xlsx_handle);
/* destroying the handle */
    free (handle);

    return FREEXL_OK;
}

#endif /* end conditional XML support */

Changes to tests/Makefile.am.

12
13
14
15
16
17
18
19


20
21
22
23
24
25
26
..
36
37
38
39
40
41
42


43
		check_excel2003_biff5_workbook \
		check_excel2003_biff8 \
		check_excel2003_biff4_1904 \
		walk_fat_oocalc97 \
		walk_sst_oocalc97 \
		check_datetime_biff8 \
		check_boolean_biff8 \
		check_oocalc97_intvalue



AM_CFLAGS = -I@srcdir@/../headers
AM_LDFLAGS = -L../src -lfreexl -lm $(GCOV_FLAGS)

TESTS = $(check_PROGRAMS)

MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
................................................................................
       testdata/simple2003_4.xls \
       testdata/simple2003_4_1904.xls \
       testdata/simple2003_4WB.xlw \
       testdata/simple2003_5WB.xls \
       testdata/datetime2003.xls \
       testdata/testcase1.xls \
       testdata/testbool.xls \


       test_under_valgrind.sh







|
>
>







 







>
>

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
38
39
40
41
42
43
44
45
46
47
		check_excel2003_biff5_workbook \
		check_excel2003_biff8 \
		check_excel2003_biff4_1904 \
		walk_fat_oocalc97 \
		walk_sst_oocalc97 \
		check_datetime_biff8 \
		check_boolean_biff8 \
		check_oocalc97_intvalue \
		check_excel_xlsx \
		check_calc_ods

AM_CFLAGS = -I@srcdir@/../headers
AM_LDFLAGS = -L../src -lfreexl -lm $(GCOV_FLAGS)

TESTS = $(check_PROGRAMS)

MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
................................................................................
       testdata/simple2003_4.xls \
       testdata/simple2003_4_1904.xls \
       testdata/simple2003_4WB.xlw \
       testdata/simple2003_5WB.xls \
       testdata/datetime2003.xls \
       testdata/testcase1.xls \
       testdata/testbool.xls \
       testdata/test_xml.ods \
       testdata/test_xml.xlsx \
       test_under_valgrind.sh

Changes to tests/Makefile.in.

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
...
116
117
118
119
120
121
122



123
124
125
126
127
128
129
...
154
155
156
157
158
159
160



161
162
163
164
165
166
167
...
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
...
617
618
619
620
621
622
623


624
625
626
627
628
629
630
...
665
666
667
668
669
670
671




672
673
674
675
676
677
678
...
705
706
707
708
709
710
711




712
713
714
715
716
717
718
...
745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768
....
1123
1124
1125
1126
1127
1128
1129














1130
1131
1132
1133
1134
1135
1136
....
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241
....
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301
1302
1303
1304
1305
	check_excel2003_biff3_error_checks$(EXEEXT) \
	check_excel2003_biff4$(EXEEXT) \
	check_excel2003_biff4_workbook$(EXEEXT) \
	check_excel2003_biff5_workbook$(EXEEXT) \
	check_excel2003_biff8$(EXEEXT) \
	check_excel2003_biff4_1904$(EXEEXT) walk_fat_oocalc97$(EXEEXT) \
	walk_sst_oocalc97$(EXEEXT) check_datetime_biff8$(EXEEXT) \
	check_boolean_biff8$(EXEEXT) check_oocalc97_intvalue$(EXEEXT)

subdir = tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
................................................................................
check_boolean_biff8_SOURCES = check_boolean_biff8.c
check_boolean_biff8_OBJECTS = check_boolean_biff8.$(OBJEXT)
check_boolean_biff8_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 



check_datetime_biff8_SOURCES = check_datetime_biff8.c
check_datetime_biff8_OBJECTS = check_datetime_biff8.$(OBJEXT)
check_datetime_biff8_LDADD = $(LDADD)
check_excel2003_biff2_SOURCES = check_excel2003_biff2.c
check_excel2003_biff2_OBJECTS = check_excel2003_biff2.$(OBJEXT)
check_excel2003_biff2_LDADD = $(LDADD)
check_excel2003_biff3_SOURCES = check_excel2003_biff3.c
................................................................................
	check_excel2003_biff5_workbook.c
check_excel2003_biff5_workbook_OBJECTS =  \
	check_excel2003_biff5_workbook.$(OBJEXT)
check_excel2003_biff5_workbook_LDADD = $(LDADD)
check_excel2003_biff8_SOURCES = check_excel2003_biff8.c
check_excel2003_biff8_OBJECTS = check_excel2003_biff8.$(OBJEXT)
check_excel2003_biff8_LDADD = $(LDADD)



check_oocalc95_SOURCES = check_oocalc95.c
check_oocalc95_OBJECTS = check_oocalc95.$(OBJEXT)
check_oocalc95_LDADD = $(LDADD)
check_oocalc97_SOURCES = check_oocalc97.c
check_oocalc97_OBJECTS = check_oocalc97.$(OBJEXT)
check_oocalc97_LDADD = $(LDADD)
check_oocalc97_intvalue_SOURCES = check_oocalc97_intvalue.c
................................................................................
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/check_boolean_biff8.Po \

	./$(DEPDIR)/check_datetime_biff8.Po \
	./$(DEPDIR)/check_excel2003_biff2.Po \
	./$(DEPDIR)/check_excel2003_biff3.Po \
	./$(DEPDIR)/check_excel2003_biff3_error_checks.Po \
	./$(DEPDIR)/check_excel2003_biff3_info.Po \
	./$(DEPDIR)/check_excel2003_biff4.Po \
	./$(DEPDIR)/check_excel2003_biff4_1904.Po \
	./$(DEPDIR)/check_excel2003_biff4_workbook.Po \
	./$(DEPDIR)/check_excel2003_biff5_workbook.Po \
	./$(DEPDIR)/check_excel2003_biff8.Po \

	./$(DEPDIR)/check_oocalc95.Po ./$(DEPDIR)/check_oocalc97.Po \
	./$(DEPDIR)/check_oocalc97_intvalue.Po \
	./$(DEPDIR)/open_excel2003.Po ./$(DEPDIR)/open_oocalc95.Po \
	./$(DEPDIR)/open_oocalc97.Po ./$(DEPDIR)/walk_fat_oocalc97.Po \
	./$(DEPDIR)/walk_sst_oocalc97.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
................................................................................
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = check_boolean_biff8.c check_datetime_biff8.c \
	check_excel2003_biff2.c check_excel2003_biff3.c \
	check_excel2003_biff3_error_checks.c \
	check_excel2003_biff3_info.c check_excel2003_biff4.c \
	check_excel2003_biff4_1904.c check_excel2003_biff4_workbook.c \
	check_excel2003_biff5_workbook.c check_excel2003_biff8.c \
	check_oocalc95.c check_oocalc97.c check_oocalc97_intvalue.c \
	open_excel2003.c open_oocalc95.c open_oocalc97.c \
	walk_fat_oocalc97.c walk_sst_oocalc97.c
DIST_SOURCES = check_boolean_biff8.c check_datetime_biff8.c \
	check_excel2003_biff2.c check_excel2003_biff3.c \
	check_excel2003_biff3_error_checks.c \
	check_excel2003_biff3_info.c check_excel2003_biff4.c \
	check_excel2003_biff4_1904.c check_excel2003_biff4_workbook.c \
	check_excel2003_biff5_workbook.c check_excel2003_biff8.c \
	check_oocalc95.c check_oocalc97.c check_oocalc97_intvalue.c \
	open_excel2003.c open_oocalc95.c open_oocalc97.c \
	walk_fat_oocalc97.c walk_sst_oocalc97.c
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
................................................................................
       testdata/simple2003_4.xls \
       testdata/simple2003_4_1904.xls \
       testdata/simple2003_4WB.xlw \
       testdata/simple2003_5WB.xls \
       testdata/datetime2003.xls \
       testdata/testcase1.xls \
       testdata/testbool.xls \


       test_under_valgrind.sh

all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
................................................................................
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

check_boolean_biff8$(EXEEXT): $(check_boolean_biff8_OBJECTS) $(check_boolean_biff8_DEPENDENCIES) $(EXTRA_check_boolean_biff8_DEPENDENCIES) 
	@rm -f check_boolean_biff8$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_boolean_biff8_OBJECTS) $(check_boolean_biff8_LDADD) $(LIBS)





check_datetime_biff8$(EXEEXT): $(check_datetime_biff8_OBJECTS) $(check_datetime_biff8_DEPENDENCIES) $(EXTRA_check_datetime_biff8_DEPENDENCIES) 
	@rm -f check_datetime_biff8$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_datetime_biff8_OBJECTS) $(check_datetime_biff8_LDADD) $(LIBS)

check_excel2003_biff2$(EXEEXT): $(check_excel2003_biff2_OBJECTS) $(check_excel2003_biff2_DEPENDENCIES) $(EXTRA_check_excel2003_biff2_DEPENDENCIES) 
	@rm -f check_excel2003_biff2$(EXEEXT)
................................................................................
check_excel2003_biff5_workbook$(EXEEXT): $(check_excel2003_biff5_workbook_OBJECTS) $(check_excel2003_biff5_workbook_DEPENDENCIES) $(EXTRA_check_excel2003_biff5_workbook_DEPENDENCIES) 
	@rm -f check_excel2003_biff5_workbook$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_excel2003_biff5_workbook_OBJECTS) $(check_excel2003_biff5_workbook_LDADD) $(LIBS)

check_excel2003_biff8$(EXEEXT): $(check_excel2003_biff8_OBJECTS) $(check_excel2003_biff8_DEPENDENCIES) $(EXTRA_check_excel2003_biff8_DEPENDENCIES) 
	@rm -f check_excel2003_biff8$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_excel2003_biff8_OBJECTS) $(check_excel2003_biff8_LDADD) $(LIBS)





check_oocalc95$(EXEEXT): $(check_oocalc95_OBJECTS) $(check_oocalc95_DEPENDENCIES) $(EXTRA_check_oocalc95_DEPENDENCIES) 
	@rm -f check_oocalc95$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_oocalc95_OBJECTS) $(check_oocalc95_LDADD) $(LIBS)

check_oocalc97$(EXEEXT): $(check_oocalc97_OBJECTS) $(check_oocalc97_DEPENDENCIES) $(EXTRA_check_oocalc97_DEPENDENCIES) 
	@rm -f check_oocalc97$(EXEEXT)
................................................................................
mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_boolean_biff8.Po@am__quote@ # am--include-marker

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_datetime_biff8.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff2.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff3.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff3_error_checks.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff3_info.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff4.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff4_1904.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff4_workbook.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff5_workbook.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff8.Po@am__quote@ # am--include-marker

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_oocalc95.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_oocalc97.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_oocalc97_intvalue.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open_excel2003.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open_oocalc95.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open_oocalc97.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/walk_fat_oocalc97.Po@am__quote@ # am--include-marker
................................................................................
check_oocalc97_intvalue.log: check_oocalc97_intvalue$(EXEEXT)
	@p='check_oocalc97_intvalue$(EXEEXT)'; \
	b='check_oocalc97_intvalue'; \
	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
	--log-file $$b.log --trs-file $$b.trs \
	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
	"$$tst" $(AM_TESTS_FD_REDIRECT)














.test.log:
	@p='$<'; \
	$(am__set_b); \
	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
	--log-file $$b.log --trs-file $$b.trs \
	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
	"$$tst" $(AM_TESTS_FD_REDIRECT)
................................................................................
clean: clean-am

clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
	mostlyclean-am

distclean: distclean-am
		-rm -f ./$(DEPDIR)/check_boolean_biff8.Po

	-rm -f ./$(DEPDIR)/check_datetime_biff8.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff2.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_error_checks.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_info.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_1904.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff5_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff8.Po

	-rm -f ./$(DEPDIR)/check_oocalc95.Po
	-rm -f ./$(DEPDIR)/check_oocalc97.Po
	-rm -f ./$(DEPDIR)/check_oocalc97_intvalue.Po
	-rm -f ./$(DEPDIR)/open_excel2003.Po
	-rm -f ./$(DEPDIR)/open_oocalc95.Po
	-rm -f ./$(DEPDIR)/open_oocalc97.Po
	-rm -f ./$(DEPDIR)/walk_fat_oocalc97.Po
................................................................................

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f ./$(DEPDIR)/check_boolean_biff8.Po

	-rm -f ./$(DEPDIR)/check_datetime_biff8.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff2.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_error_checks.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_info.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_1904.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff5_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff8.Po

	-rm -f ./$(DEPDIR)/check_oocalc95.Po
	-rm -f ./$(DEPDIR)/check_oocalc97.Po
	-rm -f ./$(DEPDIR)/check_oocalc97_intvalue.Po
	-rm -f ./$(DEPDIR)/open_excel2003.Po
	-rm -f ./$(DEPDIR)/open_oocalc95.Po
	-rm -f ./$(DEPDIR)/open_oocalc97.Po
	-rm -f ./$(DEPDIR)/walk_fat_oocalc97.Po







|
>







 







>
>
>







 







>
>
>







 







>










>
|







 







|
|
|



|
|
|
|
|
|



|
|
|







 







>
>







 







>
>
>
>







 







>
>
>
>







 







>










>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>










>







 







>










>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
...
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
....
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
....
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
....
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
	check_excel2003_biff3_error_checks$(EXEEXT) \
	check_excel2003_biff4$(EXEEXT) \
	check_excel2003_biff4_workbook$(EXEEXT) \
	check_excel2003_biff5_workbook$(EXEEXT) \
	check_excel2003_biff8$(EXEEXT) \
	check_excel2003_biff4_1904$(EXEEXT) walk_fat_oocalc97$(EXEEXT) \
	walk_sst_oocalc97$(EXEEXT) check_datetime_biff8$(EXEEXT) \
	check_boolean_biff8$(EXEEXT) check_oocalc97_intvalue$(EXEEXT) \
	check_excel_xlsx$(EXEEXT) check_calc_ods$(EXEEXT)
subdir = tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
................................................................................
check_boolean_biff8_SOURCES = check_boolean_biff8.c
check_boolean_biff8_OBJECTS = check_boolean_biff8.$(OBJEXT)
check_boolean_biff8_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 
check_calc_ods_SOURCES = check_calc_ods.c
check_calc_ods_OBJECTS = check_calc_ods.$(OBJEXT)
check_calc_ods_LDADD = $(LDADD)
check_datetime_biff8_SOURCES = check_datetime_biff8.c
check_datetime_biff8_OBJECTS = check_datetime_biff8.$(OBJEXT)
check_datetime_biff8_LDADD = $(LDADD)
check_excel2003_biff2_SOURCES = check_excel2003_biff2.c
check_excel2003_biff2_OBJECTS = check_excel2003_biff2.$(OBJEXT)
check_excel2003_biff2_LDADD = $(LDADD)
check_excel2003_biff3_SOURCES = check_excel2003_biff3.c
................................................................................
	check_excel2003_biff5_workbook.c
check_excel2003_biff5_workbook_OBJECTS =  \
	check_excel2003_biff5_workbook.$(OBJEXT)
check_excel2003_biff5_workbook_LDADD = $(LDADD)
check_excel2003_biff8_SOURCES = check_excel2003_biff8.c
check_excel2003_biff8_OBJECTS = check_excel2003_biff8.$(OBJEXT)
check_excel2003_biff8_LDADD = $(LDADD)
check_excel_xlsx_SOURCES = check_excel_xlsx.c
check_excel_xlsx_OBJECTS = check_excel_xlsx.$(OBJEXT)
check_excel_xlsx_LDADD = $(LDADD)
check_oocalc95_SOURCES = check_oocalc95.c
check_oocalc95_OBJECTS = check_oocalc95.$(OBJEXT)
check_oocalc95_LDADD = $(LDADD)
check_oocalc97_SOURCES = check_oocalc97.c
check_oocalc97_OBJECTS = check_oocalc97.$(OBJEXT)
check_oocalc97_LDADD = $(LDADD)
check_oocalc97_intvalue_SOURCES = check_oocalc97_intvalue.c
................................................................................
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/check_boolean_biff8.Po \
	./$(DEPDIR)/check_calc_ods.Po \
	./$(DEPDIR)/check_datetime_biff8.Po \
	./$(DEPDIR)/check_excel2003_biff2.Po \
	./$(DEPDIR)/check_excel2003_biff3.Po \
	./$(DEPDIR)/check_excel2003_biff3_error_checks.Po \
	./$(DEPDIR)/check_excel2003_biff3_info.Po \
	./$(DEPDIR)/check_excel2003_biff4.Po \
	./$(DEPDIR)/check_excel2003_biff4_1904.Po \
	./$(DEPDIR)/check_excel2003_biff4_workbook.Po \
	./$(DEPDIR)/check_excel2003_biff5_workbook.Po \
	./$(DEPDIR)/check_excel2003_biff8.Po \
	./$(DEPDIR)/check_excel_xlsx.Po ./$(DEPDIR)/check_oocalc95.Po \
	./$(DEPDIR)/check_oocalc97.Po \
	./$(DEPDIR)/check_oocalc97_intvalue.Po \
	./$(DEPDIR)/open_excel2003.Po ./$(DEPDIR)/open_oocalc95.Po \
	./$(DEPDIR)/open_oocalc97.Po ./$(DEPDIR)/walk_fat_oocalc97.Po \
	./$(DEPDIR)/walk_sst_oocalc97.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
................................................................................
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = check_boolean_biff8.c check_calc_ods.c \
	check_datetime_biff8.c check_excel2003_biff2.c \
	check_excel2003_biff3.c check_excel2003_biff3_error_checks.c \
	check_excel2003_biff3_info.c check_excel2003_biff4.c \
	check_excel2003_biff4_1904.c check_excel2003_biff4_workbook.c \
	check_excel2003_biff5_workbook.c check_excel2003_biff8.c \
	check_excel_xlsx.c check_oocalc95.c check_oocalc97.c \
	check_oocalc97_intvalue.c open_excel2003.c open_oocalc95.c \
	open_oocalc97.c walk_fat_oocalc97.c walk_sst_oocalc97.c
DIST_SOURCES = check_boolean_biff8.c check_calc_ods.c \
	check_datetime_biff8.c check_excel2003_biff2.c \
	check_excel2003_biff3.c check_excel2003_biff3_error_checks.c \
	check_excel2003_biff3_info.c check_excel2003_biff4.c \
	check_excel2003_biff4_1904.c check_excel2003_biff4_workbook.c \
	check_excel2003_biff5_workbook.c check_excel2003_biff8.c \
	check_excel_xlsx.c check_oocalc95.c check_oocalc97.c \
	check_oocalc97_intvalue.c open_excel2003.c open_oocalc95.c \
	open_oocalc97.c walk_fat_oocalc97.c walk_sst_oocalc97.c
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
................................................................................
       testdata/simple2003_4.xls \
       testdata/simple2003_4_1904.xls \
       testdata/simple2003_4WB.xlw \
       testdata/simple2003_5WB.xls \
       testdata/datetime2003.xls \
       testdata/testcase1.xls \
       testdata/testbool.xls \
       testdata/test_xml.ods \
       testdata/test_xml.xlsx \
       test_under_valgrind.sh

all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
................................................................................
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

check_boolean_biff8$(EXEEXT): $(check_boolean_biff8_OBJECTS) $(check_boolean_biff8_DEPENDENCIES) $(EXTRA_check_boolean_biff8_DEPENDENCIES) 
	@rm -f check_boolean_biff8$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_boolean_biff8_OBJECTS) $(check_boolean_biff8_LDADD) $(LIBS)

check_calc_ods$(EXEEXT): $(check_calc_ods_OBJECTS) $(check_calc_ods_DEPENDENCIES) $(EXTRA_check_calc_ods_DEPENDENCIES) 
	@rm -f check_calc_ods$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_calc_ods_OBJECTS) $(check_calc_ods_LDADD) $(LIBS)

check_datetime_biff8$(EXEEXT): $(check_datetime_biff8_OBJECTS) $(check_datetime_biff8_DEPENDENCIES) $(EXTRA_check_datetime_biff8_DEPENDENCIES) 
	@rm -f check_datetime_biff8$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_datetime_biff8_OBJECTS) $(check_datetime_biff8_LDADD) $(LIBS)

check_excel2003_biff2$(EXEEXT): $(check_excel2003_biff2_OBJECTS) $(check_excel2003_biff2_DEPENDENCIES) $(EXTRA_check_excel2003_biff2_DEPENDENCIES) 
	@rm -f check_excel2003_biff2$(EXEEXT)
................................................................................
check_excel2003_biff5_workbook$(EXEEXT): $(check_excel2003_biff5_workbook_OBJECTS) $(check_excel2003_biff5_workbook_DEPENDENCIES) $(EXTRA_check_excel2003_biff5_workbook_DEPENDENCIES) 
	@rm -f check_excel2003_biff5_workbook$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_excel2003_biff5_workbook_OBJECTS) $(check_excel2003_biff5_workbook_LDADD) $(LIBS)

check_excel2003_biff8$(EXEEXT): $(check_excel2003_biff8_OBJECTS) $(check_excel2003_biff8_DEPENDENCIES) $(EXTRA_check_excel2003_biff8_DEPENDENCIES) 
	@rm -f check_excel2003_biff8$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_excel2003_biff8_OBJECTS) $(check_excel2003_biff8_LDADD) $(LIBS)

check_excel_xlsx$(EXEEXT): $(check_excel_xlsx_OBJECTS) $(check_excel_xlsx_DEPENDENCIES) $(EXTRA_check_excel_xlsx_DEPENDENCIES) 
	@rm -f check_excel_xlsx$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_excel_xlsx_OBJECTS) $(check_excel_xlsx_LDADD) $(LIBS)

check_oocalc95$(EXEEXT): $(check_oocalc95_OBJECTS) $(check_oocalc95_DEPENDENCIES) $(EXTRA_check_oocalc95_DEPENDENCIES) 
	@rm -f check_oocalc95$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(check_oocalc95_OBJECTS) $(check_oocalc95_LDADD) $(LIBS)

check_oocalc97$(EXEEXT): $(check_oocalc97_OBJECTS) $(check_oocalc97_DEPENDENCIES) $(EXTRA_check_oocalc97_DEPENDENCIES) 
	@rm -f check_oocalc97$(EXEEXT)
................................................................................
mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_boolean_biff8.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_calc_ods.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_datetime_biff8.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff2.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff3.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff3_error_checks.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff3_info.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff4.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff4_1904.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff4_workbook.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff5_workbook.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel2003_biff8.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_excel_xlsx.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_oocalc95.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_oocalc97.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_oocalc97_intvalue.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open_excel2003.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open_oocalc95.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open_oocalc97.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/walk_fat_oocalc97.Po@am__quote@ # am--include-marker
................................................................................
check_oocalc97_intvalue.log: check_oocalc97_intvalue$(EXEEXT)
	@p='check_oocalc97_intvalue$(EXEEXT)'; \
	b='check_oocalc97_intvalue'; \
	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
	--log-file $$b.log --trs-file $$b.trs \
	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
	"$$tst" $(AM_TESTS_FD_REDIRECT)
check_excel_xlsx.log: check_excel_xlsx$(EXEEXT)
	@p='check_excel_xlsx$(EXEEXT)'; \
	b='check_excel_xlsx'; \
	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
	--log-file $$b.log --trs-file $$b.trs \
	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
	"$$tst" $(AM_TESTS_FD_REDIRECT)
check_calc_ods.log: check_calc_ods$(EXEEXT)
	@p='check_calc_ods$(EXEEXT)'; \
	b='check_calc_ods'; \
	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
	--log-file $$b.log --trs-file $$b.trs \
	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
	"$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
	@p='$<'; \
	$(am__set_b); \
	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
	--log-file $$b.log --trs-file $$b.trs \
	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
	"$$tst" $(AM_TESTS_FD_REDIRECT)
................................................................................
clean: clean-am

clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
	mostlyclean-am

distclean: distclean-am
		-rm -f ./$(DEPDIR)/check_boolean_biff8.Po
	-rm -f ./$(DEPDIR)/check_calc_ods.Po
	-rm -f ./$(DEPDIR)/check_datetime_biff8.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff2.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_error_checks.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_info.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_1904.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff5_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff8.Po
	-rm -f ./$(DEPDIR)/check_excel_xlsx.Po
	-rm -f ./$(DEPDIR)/check_oocalc95.Po
	-rm -f ./$(DEPDIR)/check_oocalc97.Po
	-rm -f ./$(DEPDIR)/check_oocalc97_intvalue.Po
	-rm -f ./$(DEPDIR)/open_excel2003.Po
	-rm -f ./$(DEPDIR)/open_oocalc95.Po
	-rm -f ./$(DEPDIR)/open_oocalc97.Po
	-rm -f ./$(DEPDIR)/walk_fat_oocalc97.Po
................................................................................

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f ./$(DEPDIR)/check_boolean_biff8.Po
	-rm -f ./$(DEPDIR)/check_calc_ods.Po
	-rm -f ./$(DEPDIR)/check_datetime_biff8.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff2.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_error_checks.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff3_info.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_1904.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff4_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff5_workbook.Po
	-rm -f ./$(DEPDIR)/check_excel2003_biff8.Po
	-rm -f ./$(DEPDIR)/check_excel_xlsx.Po
	-rm -f ./$(DEPDIR)/check_oocalc95.Po
	-rm -f ./$(DEPDIR)/check_oocalc97.Po
	-rm -f ./$(DEPDIR)/check_oocalc97_intvalue.Po
	-rm -f ./$(DEPDIR)/open_excel2003.Po
	-rm -f ./$(DEPDIR)/open_oocalc95.Po
	-rm -f ./$(DEPDIR)/open_oocalc97.Po
	-rm -f ./$(DEPDIR)/walk_fat_oocalc97.Po

Added tests/check_calc_ods.c.







































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
/* 
/ check_calc_ods.c
/
/ Test cases for Open/LibreOffice Calc ODS format files
/
/ version  2.0, 2021 June 06
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "freexl.h"

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

int
main (int argc, char *argv[])
{
#ifdef OMIT_XMLDOC		/* XML support is not enabled */
    fprintf (stderr,
	     "Sorry, this version of check_calc_ods was built by disabling support XML documents\n");
    return 0;
#else
    const void *handle;
    int ret;
    unsigned int info;
    const char *worksheet_name;
    unsigned short active_idx;
    unsigned int num_rows;
    unsigned short num_columns;
    FreeXL_CellValue cell_value;

    ret = freexl_open_ods ("testdata/test_xml.ods", &handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "OPEN ERROR: %d\n", ret);
	  return -1;
      }

    ret = freexl_get_worksheets_count (handle, &info);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr,
		   "GET_WORKSHEETS_COUNT ERROR for ODS worksheet count: %d\n",
		   ret);
	  return -3;
      }
    if (info != 2)
      {
	  fprintf (stderr, "Unexpected ODS worksheet count: %d\n", info);
	  return -4;
      }

    /* We start with the first worksheet, zero index */
    ret = freexl_get_worksheet_name (handle, 0, &worksheet_name);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet name: %d\n", ret);
	  return -5;
      }
    if (strcmp (worksheet_name, "First Sheet") != 0)
      {
	  fprintf (stderr, "Unexpected worksheet name: %s\n", worksheet_name);
	  return -6;
      }

    ret = freexl_select_active_worksheet (handle, 0);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error setting active worksheet: %d\n", ret);
	  return -7;
      }

    ret = freexl_get_active_worksheet (handle, &active_idx);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting active worksheet: %d\n", ret);
	  return -8;
      }
    if (active_idx != 0)
      {
	  fprintf (stderr, "Unexpected active sheet: %d\n", info);
	  return -9;
      }

    ret = freexl_worksheet_dimensions (handle, &num_rows, &num_columns);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet dimensions: %d\n", ret);
	  return -10;
      }
    if ((num_rows != 31) || (num_columns != 66))
      {
	  fprintf (stderr, "Unexpected active sheet dimensions: %u x %u\n",
		   num_rows, num_columns);
	  return -11;
      }

    ret = freexl_get_cell_value (handle, 0, 0, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (0,0): %d\n", ret);
	  return -12;
      }
    if (cell_value.type != FREEXL_CELL_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (0,0) type: %u\n", cell_value.type);
	  return -13;
      }
    if (strcmp (cell_value.value.text_value, "alpha") != 0)
      {
	  fprintf (stderr, "Unexpected cell (0,0) value: %s\n",
		   cell_value.value.text_value);
	  return -14;
      }

    ret = freexl_get_cell_value (handle, 1, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (1,1): %d\n", ret);
	  return -15;
      }
    if (cell_value.type != FREEXL_CELL_INT)
      {
	  fprintf (stderr, "Unexpected cell (1,1) type: %u\n", cell_value.type);
	  return -16;
      }
    if (cell_value.value.int_value != 1)
      {
	  fprintf (stderr, "Unexpected cell (1,1) value: %d\n",
		   cell_value.value.int_value);
	  return -17;
      }

    ret = freexl_get_cell_value (handle, 2, 2, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (2,2): %d\n", ret);
	  return -18;
      }
    if (cell_value.type != FREEXL_CELL_DOUBLE)
      {
	  fprintf (stderr, "Unexpected cell (2,2) type: %u\n", cell_value.type);
	  return -19;
      }
    if (cell_value.value.double_value != 1.20)
      {
	  fprintf (stderr, "Unexpected cell (2,2) value: %f\n",
		   cell_value.value.double_value);
	  return -20;
      }

    ret = freexl_get_cell_value (handle, 3, 3, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (3,3): %d\n", ret);
	  return -21;
      }
    if (cell_value.type != FREEXL_CELL_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (3,3) type: %u\n", cell_value.type);
	  return -22;
      }
    if (strcmp (cell_value.value.text_value, "1956-02-02") != 0)
      {
	  fprintf (stderr, "Unexpected cell (3,3) value: %s\n",
		   cell_value.value.text_value);
	  return -23;
      }

    ret = freexl_get_cell_value (handle, 5, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (5,1): %d\n", ret);
	  return -24;
      }
    if (cell_value.type != FREEXL_CELL_DOUBLE)
      {
	  fprintf (stderr, "Unexpected cell (5,1) type: %u\n", cell_value.type);
	  return -25;
      }
    if (cell_value.value.double_value != 1000000.50)
      {
	  fprintf (stderr, "Unexpected cell (5,1) value: %f\n",
		   cell_value.value.double_value);
	  return -26;
      }

    ret = freexl_get_cell_value (handle, 8, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (8,1): %d\n", ret);
	  return -27;
      }
    if (cell_value.type != FREEXL_CELL_DOUBLE)
      {
	  fprintf (stderr, "Unexpected cell (8,1) type: %u\n", cell_value.type);
	  return -28;
      }
    if (cell_value.value.double_value != 1550.65)
      {
	  fprintf (stderr, "Unexpected cell (8,1) value: %f\n",
		   cell_value.value.double_value);
	  return -29;
      }

    ret = freexl_get_cell_value (handle, 9, 3, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (9,3): %d\n", ret);
	  return -30;
      }
    if (cell_value.type != FREEXL_CELL_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (9,3) type: %u\n", cell_value.type);
	  return -31;
      }
    if (strcmp (cell_value.value.text_value, "1956-02-02 19:23:00") != 0)
      {
	  fprintf (stderr, "Unexpected cell (9,3) value: %s\n",
		   cell_value.value.text_value);
	  return -32;
      }

    ret = freexl_get_cell_value (handle, 15, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (15,1): %d\n", ret);
	  return -33;
      }
    if (cell_value.type != FREEXL_CELL_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (15,1) type: %u\n",
		   cell_value.type);
	  return -34;
      }
    if (strcmp (cell_value.value.text_value, "arezzo&firenze") != 0)
      {
	  fprintf (stderr, "Unexpected cell (15,1) value: %s\n",
		   cell_value.value.text_value);
	  return -35;
      }

    ret = freexl_get_cell_value (handle, 30, 65, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (30, 65): %d\n", ret);
	  return -36;
      }
    if (cell_value.type != FREEXL_CELL_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (30, 65) type: %u\n",
		   cell_value.type);
	  return -37;
      }
    if (strcmp (cell_value.value.text_value, "BN marker") != 0)
      {
	  fprintf (stderr, "Unexpected cell (30, 65) value: %s\n",
		   cell_value.value.text_value);
	  return -38;
      }

    /* testing the second worksheet, index 1 */
    ret = freexl_get_worksheet_name (handle, 1, &worksheet_name);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet name #2: %d\n", ret);
	  return -39;
      }
    if (strcmp (worksheet_name, "Second Sheet") != 0)
      {
	  fprintf (stderr, "Unexpected worksheet name #2: %s\n",
		   worksheet_name);
	  return -40;
      }

    ret = freexl_select_active_worksheet (handle, 1);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error setting active worksheet#2: %d\n", ret);
	  return -41;
      }

    ret = freexl_get_active_worksheet (handle, &active_idx);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting active worksheet#2: %d\n", ret);
	  return -42;
      }
    if (active_idx != 1)
      {
	  fprintf (stderr, "Unexpected active sheet #2: %d\n", info);
	  return -43;
      }

    ret = freexl_worksheet_dimensions (handle, &num_rows, &num_columns);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet dimensions #2: %d\n", ret);
	  return -44;
      }
    if ((num_rows != 14) || (num_columns != 8))
      {
	  fprintf (stderr, "Unexpected active sheet dimensions#2: %u x %u\n",
		   num_rows, num_columns);
	  return -45;
      }

    ret = freexl_get_cell_value (handle, 4, 2, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value#2 (4,3): %d\n", ret);
	  return -46;
      }
    if (cell_value.type != FREEXL_CELL_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (4,2) type#2: %u\n",
		   cell_value.type);
	  return -47;
      }
    if (strcmp (cell_value.value.text_value, "some meaningless text") != 0)
      {
	  fprintf (stderr, "Unexpected cell (4,2) value: %s\n",
		   cell_value.value.text_value);
	  return -48;
      }

    /* error cases */
    ret = freexl_get_cell_value (handle, 1, 82, &cell_value);
    if (ret != FREEXL_ILLEGAL_CELL_ROW_COL)
      {
	  fprintf (stderr, "Unexpected result for (1,82): %d\n", ret);
	  return -49;
      }
    ret = freexl_get_cell_value (handle, 35, 6, &cell_value);
    if (ret != FREEXL_ILLEGAL_CELL_ROW_COL)
      {
	  fprintf (stderr, "Unexpected result for (35,6): %d\n", ret);
	  return -50;
      }
    ret = freexl_get_worksheet_name (handle, 10, &worksheet_name);
    if (ret == FREEXL_OK)
      {
	  fprintf (stderr, "Unexpected result getting worksheet name: %d\n",
		   ret);
	  return -51;
      }
    ret = freexl_select_active_worksheet (handle, 10);
    if (ret == FREEXL_OK)
      {
	  fprintf (stderr, "Unexpected result  setting active worksheet: %d\n",
		   ret);
	  return -52;
      }

/* testing GetStringsCount */
    ret = freexl_get_strings_count (handle, &info);
    if (ret == FREEXL_OK)
      {
	  fprintf (stderr, "Unexpected XLSX worksheet count: %d\n", ret);
	  return -53;
      }

    ret = freexl_close (handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "CLOSE ERROR: %d\n", ret);
	  return -2;
      }

    if (argc > 1 || argv[0] == NULL)
	argc = 1;		/* silencing stupid compiler warnings */

    return 0;
#endif /* end conditional XML support */
}

Added tests/check_excel_xlsx.c.



















































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/* 
/ check_excel_xlsx.c
/
/ Test cases for Excel XLSX format files
/
/ version  2.0, 2021 June 06
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the FreeXL library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2021
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "freexl.h"

#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif

int
main (int argc, char *argv[])
{
#ifdef OMIT_XMLDOC		/* XML support is not enabled */
    fprintf (stderr,
	     "Sorry, this version of check_excel_xlsx was built by disabling support XML documents\n");
    return 0;
#else
    const void *handle;
    int ret;
    unsigned int info;
    const char *worksheet_name;
    unsigned short active_idx;
    unsigned int num_rows;
    unsigned short num_columns;
    FreeXL_CellValue cell_value;

    ret = freexl_open_xlsx ("testdata/test_xml.xlsx", &handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "OPEN ERROR: %d\n", ret);
	  return -1;
      }

    ret = freexl_get_worksheets_count (handle, &info);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr,
		   "GET_WORKSHEETS_COUNT ERROR for XLSX worksheet count: %d\n",
		   ret);
	  return -3;
      }
    if (info != 2)
      {
	  fprintf (stderr, "Unexpected XLSX worksheet count: %d\n", info);
	  return -4;
      }

    /* We start with the first worksheet, zero index */
    ret = freexl_get_worksheet_name (handle, 0, &worksheet_name);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet name: %d\n", ret);
	  return -5;
      }
    if (strcmp (worksheet_name, "First Sheet") != 0)
      {
	  fprintf (stderr, "Unexpected worksheet name: %s\n", worksheet_name);
	  return -6;
      }

    ret = freexl_select_active_worksheet (handle, 0);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error setting active worksheet: %d\n", ret);
	  return -7;
      }

    ret = freexl_get_active_worksheet (handle, &active_idx);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting active worksheet: %d\n", ret);
	  return -8;
      }
    if (active_idx != 0)
      {
	  fprintf (stderr, "Unexpected active sheet: %d\n", info);
	  return -9;
      }

    ret = freexl_worksheet_dimensions (handle, &num_rows, &num_columns);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet dimensions: %d\n", ret);
	  return -10;
      }
    if ((num_rows != 31) || (num_columns != 66))
      {
	  fprintf (stderr, "Unexpected active sheet dimensions: %u x %u\n",
		   num_rows, num_columns);
	  return -11;
      }

    ret = freexl_get_cell_value (handle, 0, 0, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (0,0): %d\n", ret);
	  return -12;
      }
    if (cell_value.type != FREEXL_CELL_SST_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (0,0) type: %u\n", cell_value.type);
	  return -13;
      }
    if (strcmp (cell_value.value.text_value, "alpha") != 0)
      {
	  fprintf (stderr, "Unexpected cell (0,0) value: %s\n",
		   cell_value.value.text_value);
	  return -14;
      }

    ret = freexl_get_cell_value (handle, 1, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (1,1): %d\n", ret);
	  return -15;
      }
    if (cell_value.type != FREEXL_CELL_INT)
      {
	  fprintf (stderr, "Unexpected cell (1,1) type: %u\n", cell_value.type);
	  return -16;
      }
    if (cell_value.value.int_value != 1)
      {
	  fprintf (stderr, "Unexpected cell (1,1) value: %d\n",
		   cell_value.value.int_value);
	  return -17;
      }

    ret = freexl_get_cell_value (handle, 2, 2, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (2,2): %d\n", ret);
	  return -18;
      }
    if (cell_value.type != FREEXL_CELL_DOUBLE)
      {
	  fprintf (stderr, "Unexpected cell (2,2) type: %u\n", cell_value.type);
	  return -19;
      }
    if (cell_value.value.double_value != 1.20)
      {
	  fprintf (stderr, "Unexpected cell (2,2) value: %f\n",
		   cell_value.value.double_value);
	  return -20;
      }

    ret = freexl_get_cell_value (handle, 3, 3, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (3,3): %d\n", ret);
	  return -21;
      }
    if (cell_value.type != FREEXL_CELL_DATE)
      {
	  fprintf (stderr, "Unexpected cell (3,3) type: %u\n", cell_value.type);
	  return -22;
      }
    if (strcmp (cell_value.value.text_value, "1956-02-02") != 0)
      {
	  fprintf (stderr, "Unexpected cell (3,3) value: %s\n",
		   cell_value.value.text_value);
	  return -23;
      }

    ret = freexl_get_cell_value (handle, 5, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (5,1): %d\n", ret);
	  return -24;
      }
    if (cell_value.type != FREEXL_CELL_DOUBLE)
      {
	  fprintf (stderr, "Unexpected cell (5,1) type: %u\n", cell_value.type);
	  return -25;
      }
    if (cell_value.value.double_value != 1000000.50)
      {
	  fprintf (stderr, "Unexpected cell (5,1) value: %f\n",
		   cell_value.value.double_value);
	  return -26;
      }

    ret = freexl_get_cell_value (handle, 8, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (8,1): %d\n", ret);
	  return -27;
      }
    if (cell_value.type != FREEXL_CELL_DOUBLE)
      {
	  fprintf (stderr, "Unexpected cell (8,1) type: %u\n", cell_value.type);
	  return -28;
      }
    if (cell_value.value.double_value != 1550.65)
      {
	  fprintf (stderr, "Unexpected cell (8,1) value: %f\n",
		   cell_value.value.double_value);
	  return -29;
      }

    ret = freexl_get_cell_value (handle, 9, 3, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (9,3): %d\n", ret);
	  return -30;
      }
    if (cell_value.type != FREEXL_CELL_DATETIME)
      {
	  fprintf (stderr, "Unexpected cell (9,3) type: %u\n", cell_value.type);
	  return -31;
      }
    if (strcmp (cell_value.value.text_value, "1956-02-02 19:23:00") != 0)
      {
	  fprintf (stderr, "Unexpected cell (9,3) value: %s\n",
		   cell_value.value.text_value);
	  return -32;
      }

    ret = freexl_get_cell_value (handle, 15, 1, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (15,1): %d\n", ret);
	  return -33;
      }
    if (cell_value.type != FREEXL_CELL_SST_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (15,1) type: %u\n",
		   cell_value.type);
	  return -34;
      }
    if (strcmp (cell_value.value.text_value, "arezzo&firenze") != 0)
      {
	  fprintf (stderr, "Unexpected cell (15,1) value: %s\n",
		   cell_value.value.text_value);
	  return -35;
      }

    ret = freexl_get_cell_value (handle, 30, 65, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value (30, 65): %d\n", ret);
	  return -36;
      }
    if (cell_value.type != FREEXL_CELL_SST_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (30, 65) type: %u\n",
		   cell_value.type);
	  return -37;
      }
    if (strcmp (cell_value.value.text_value, "BN marker") != 0)
      {
	  fprintf (stderr, "Unexpected cell (30, 65) value: %s\n",
		   cell_value.value.text_value);
	  return -38;
      }

    /* testing the second worksheet, index 1 */
    ret = freexl_get_worksheet_name (handle, 1, &worksheet_name);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet name #2: %d\n", ret);
	  return -39;
      }
    if (strcmp (worksheet_name, "Second Sheet") != 0)
      {
	  fprintf (stderr, "Unexpected worksheet name #2: %s\n",
		   worksheet_name);
	  return -40;
      }

    ret = freexl_select_active_worksheet (handle, 1);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error setting active worksheet#2: %d\n", ret);
	  return -41;
      }

    ret = freexl_get_active_worksheet (handle, &active_idx);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting active worksheet#2: %d\n", ret);
	  return -42;
      }
    if (active_idx != 1)
      {
	  fprintf (stderr, "Unexpected active sheet #2: %d\n", info);
	  return -43;
      }

    ret = freexl_worksheet_dimensions (handle, &num_rows, &num_columns);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting worksheet dimensions #2: %d\n", ret);
	  return -44;
      }
    if ((num_rows != 14) || (num_columns != 8))
      {
	  fprintf (stderr, "Unexpected active sheet dimensions#2: %u x %u\n",
		   num_rows, num_columns);
	  return -45;
      }

    ret = freexl_get_cell_value (handle, 4, 2, &cell_value);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting cell value#2 (4,3): %d\n", ret);
	  return -46;
      }
    if (cell_value.type != FREEXL_CELL_SST_TEXT)
      {
	  fprintf (stderr, "Unexpected cell (4,2) type#2: %u\n",
		   cell_value.type);
	  return -47;
      }
    if (strcmp (cell_value.value.text_value, "some meaningless text") != 0)
      {
	  fprintf (stderr, "Unexpected cell (4,2) value: %s\n",
		   cell_value.value.text_value);
	  return -48;
      }

    /* error cases */
    ret = freexl_get_cell_value (handle, 1, 82, &cell_value);
    if (ret != FREEXL_ILLEGAL_CELL_ROW_COL)
      {
	  fprintf (stderr, "Unexpected result for (1,82): %d\n", ret);
	  return -49;
      }
    ret = freexl_get_cell_value (handle, 35, 6, &cell_value);
    if (ret != FREEXL_ILLEGAL_CELL_ROW_COL)
      {
	  fprintf (stderr, "Unexpected result for (35,6): %d\n", ret);
	  return -50;
      }
    ret = freexl_get_worksheet_name (handle, 10, &worksheet_name);
    if (ret == FREEXL_OK)
      {
	  fprintf (stderr, "Unexpected result getting worksheet name: %d\n",
		   ret);
	  return -51;
      }
    ret = freexl_select_active_worksheet (handle, 10);
    if (ret == FREEXL_OK)
      {
	  fprintf (stderr, "Unexpected result  setting active worksheet: %d\n",
		   ret);
	  return -52;
      }

/* testing GetStringsCount */
    ret = freexl_get_strings_count (handle, &info);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "Error getting XLSX Single Strings count: %d\n",
		   ret);
	  return -53;
      }
    if (info != 21)
      {
	  fprintf (stderr, "Unexpected XLSX worksheet count: %d\n", info);
	  return -54;
      }

    ret = freexl_close (handle);
    if (ret != FREEXL_OK)
      {
	  fprintf (stderr, "CLOSE ERROR: %d\n", ret);
	  return -2;
      }

    if (argc > 1 || argv[0] == NULL)
	argc = 1;		/* silencing stupid compiler warnings */

    return 0;
#endif /* end conditional XML support */
}

Added tests/testdata/test_xml.ods.

cannot compute difference between binary files

Added tests/testdata/test_xml.xlsx.

cannot compute difference between binary files