浏览代码

Merge pull request #94 from viest/dev

fix : build bunled library version, fixes #90
viest 6 年之前
父节点
当前提交
951c8314ce
共有 74 个文件被更改,包括 266 次插入42609 次删除
  1. 31 18
      .appveyor.yml
  2. 4 0
      .gitmodules
  3. 1 0
      .travis.yml
  4. 184 0
      backup/.appveyor.yml.backup
  5. 28 0
      backup/config.w32.backup
  6. 10 4
      config.m4
  7. 7 17
      config.w32
  8. 1 0
      library
  9. 0 150
      library/License.txt
  10. 0 131
      library/include/crypt.h
  11. 0 208
      library/include/ioapi.h
  12. 0 28
      library/include/iowin32.h
  13. 0 37
      library/include/mztools.h
  14. 0 53
      library/include/tmpfileplus.h
  15. 0 437
      library/include/unzip.h
  16. 0 23
      library/include/xlsxwriter.h
  17. 0 79
      library/include/xlsxwriter/app.h
  18. 0 3577
      library/include/xlsxwriter/chart.h
  19. 0 380
      library/include/xlsxwriter/common.h
  20. 0 74
      library/include/xlsxwriter/content_types.h
  21. 0 51
      library/include/xlsxwriter/core.h
  22. 0 52
      library/include/xlsxwriter/custom.h
  23. 0 111
      library/include/xlsxwriter/drawing.h
  24. 0 1214
      library/include/xlsxwriter/format.h
  25. 0 76
      library/include/xlsxwriter/hash_table.h
  26. 0 85
      library/include/xlsxwriter/packager.h
  27. 0 77
      library/include/xlsxwriter/relationships.h
  28. 0 83
      library/include/xlsxwriter/shared_strings.h
  29. 0 77
      library/include/xlsxwriter/styles.h
  30. 0 47
      library/include/xlsxwriter/theme.h
  31. 0 214
      library/include/xlsxwriter/third_party/ioapi.h
  32. 0 694
      library/include/xlsxwriter/third_party/queue.h
  33. 0 53
      library/include/xlsxwriter/third_party/tmpfileplus.h
  34. 0 801
      library/include/xlsxwriter/third_party/tree.h
  35. 0 375
      library/include/xlsxwriter/third_party/zip.h
  36. 0 172
      library/include/xlsxwriter/utility.h
  37. 0 751
      library/include/xlsxwriter/workbook.h
  38. 0 3119
      library/include/xlsxwriter/worksheet.h
  39. 0 178
      library/include/xlsxwriter/xmlwriter.h
  40. 0 367
      library/include/zip.h
  41. 0 443
      library/src/app.c
  42. 0 6403
      library/src/chart.c
  43. 0 345
      library/src/content_types.c
  44. 0 293
      library/src/core.c
  45. 0 224
      library/src/custom.c
  46. 0 746
      library/src/drawing.c
  47. 0 223
      library/src/hash_table.c
  48. 0 961
      library/src/packager.c
  49. 0 245
      library/src/relationships.c
  50. 0 266
      library/src/shared_strings.c
  51. 0 1088
      library/src/styles.c
  52. 0 348
      library/src/theme.c
  53. 0 555
      library/src/utility.c
  54. 0 1913
      library/src/workbook.c
  55. 0 5739
      library/src/worksheet.c
  56. 0 728
      library/src/xlsx_format.c
  57. 0 355
      library/src/xmlwriter.c
  58. 0 5
      library/third_party/minizip/README.txt
  59. 0 131
      library/third_party/minizip/crypt.h
  60. 0 247
      library/third_party/minizip/ioapi.c
  61. 0 208
      library/third_party/minizip/ioapi.h
  62. 0 456
      library/third_party/minizip/iowin32.c
  63. 0 28
      library/third_party/minizip/iowin32.h
  64. 0 7
      library/third_party/minizip/iowin32.loT
  65. 0 660
      library/third_party/minizip/miniunz.c
  66. 0 520
      library/third_party/minizip/minizip.c
  67. 0 291
      library/third_party/minizip/mztools.c
  68. 0 37
      library/third_party/minizip/mztools.h
  69. 0 2125
      library/third_party/minizip/unzip.c
  70. 0 437
      library/third_party/minizip/unzip.h
  71. 0 2007
      library/third_party/minizip/zip.c
  72. 0 367
      library/third_party/minizip/zip.h
  73. 0 342
      library/third_party/tmpfileplus/tmpfileplus.c
  74. 0 53
      library/third_party/tmpfileplus/tmpfileplus.h

+ 31 - 18
.appveyor.yml

@@ -23,25 +23,26 @@ install:
                         7z x c:\build-cache\$bname -oc:\build-cache
                         move c:\build-cache\$dname0 c:\build-cache\$dname1
                 }
-                $lname2 = 'zlib-1.2.11.tar.gz'
-                $lname3 = 'zlib'
+                $lname0 = 'zlib-' + $env:ZLIB_VER + '-' + $env:VC + '-' + $env:ARCH + '.zip'
+                $lname1 = 'zlib'
+                if (-not (Test-Path c:\build-cache\$lname0)) {
+                        $zliurl = "https://windows.php.net/downloads/php-sdk/deps/" + $env:VC + "/" + $env:ARCH+ "/" + $lname0
+                        Invoke-WebRequest $zliurl -OutFile "c:\build-cache\$lname0"
+                }
+                if (-not (Test-Path c:\build-cache\$lname1)) {
+                        & 7z x c:\build-cache\$lname0 -oc:\build-cache\$lname1
+                }
+                $lname2 = 'libxlsxwriter-' + $env:LIBXLSXWRITER_VER + '-' + $env:VC + '-' + $env:ARCH + '.zip'
+                $lname3 = 'libxlsxwriter'
                 if (-not (Test-Path c:\build-cache\$lname2)) {
-                        $zliurl = "http://zlib.net/" + $lname2
-                        Invoke-WebRequest $zliurl -OutFile "c:\build-cache\$lname2"
+                        $url = "https://windows.php.net/downloads/pecl/deps/" + $lname2
+                        Invoke-WebRequest $url -OutFile "c:\build-cache\$lname2"
                 }
                 if (-not (Test-Path c:\build-cache\$lname3)) {
-                        & 7z x c:\build-cache\$lname2 -oc:\build-cache
-                        & 7z x c:\build-cache\zlib-1.2.11.tar -oc:\build-cache\$lname3
-                }
-                if (-not (Test-Path c:\build-cache\$lname3\Release)) {
-                       cd c:\build-cache\$lname3\zlib-1.2.11
-                       $cmakegen = 'Visual Studio 15 2017'
-                       if ($env:VC -Match "vc14") {
-                              $cmakegen = "Visual Studio 14 2015"
-                       }
-                       & cmake -G $cmakegen -DCMAKE_BUILD_TYPE="Release" -DCMAKE_C_FLAGS_RELEASE="/MT"
-                       & cmake --build . --config "Release"
+                        & 7z x c:\build-cache\$lname2 -oc:\build-cache\$lname3
                 }
+                move c:\build-cache\zlib\lib\*.*     c:\build-cache\libxlsxwriter\lib
+                move c:\build-cache\zlib\include\*.* c:\build-cache\libxlsxwriter\include
 
 cache:
         c:\build-cache -> .appveyor.yml
@@ -54,61 +55,73 @@ environment:
                   ARCH: x64
                   VC: vc14
                   PHP_VER: 7.0.28
+                  ZLIB_VER: 1.2.8
                   TS: 0
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x64
                   VC: vc14
                   PHP_VER: 7.0.28
+                  ZLIB_VER: 1.2.8
                   TS: 1
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x86
                   VC: vc14
                   PHP_VER: 7.0.28
+                  ZLIB_VER: 1.2.8
                   TS: 0
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x86
                   VC: vc14
                   PHP_VER: 7.0.28
+                  ZLIB_VER: 1.2.8
                   TS: 1
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x64
                   VC: vc14
                   PHP_VER: 7.1.15
+                  ZLIB_VER: 1.2.8
                   TS: 0
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x64
                   VC: vc14
                   PHP_VER: 7.1.15
+                  ZLIB_VER: 1.2.8
                   TS: 1
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x86
                   VC: vc14
                   PHP_VER: 7.1.15
+                  ZLIB_VER: 1.2.8
                   TS: 0
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
                   ARCH: x86
                   VC: vc14
                   PHP_VER: 7.1.15
+                  ZLIB_VER: 1.2.8
                   TS: 1
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
                   ARCH: x64
                   VC: vc15
                   PHP_VER: 7.2.3
+                  ZLIB_VER: 1.2.11
                   TS: 0
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
                   ARCH: x64
                   VC: vc15
                   PHP_VER: 7.2.3
+                  ZLIB_VER: 1.2.11
                   TS: 1
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
                   ARCH: x86
                   VC: vc15
                   PHP_VER: 7.2.3
+                  ZLIB_VER: 1.2.11
                   TS: 0
                 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
                   ARCH: x86
                   VC: vc15
                   PHP_VER: 7.2.3
+                  ZLIB_VER: 1.2.11
                   TS: 1
 
 build_script:
@@ -134,7 +147,7 @@ build_script:
                 #echo "" | Out-File -Encoding "ASCII" -Append task.bat
                 echo "" | Out-File -Encoding "ASCII" task.bat
                 echo "call phpize 2>&1" | Out-File -Encoding "ASCII" -Append task.bat
-                $conf_cmd = 'call configure --with-xlswriter --with-extra-libs=c:\build-cache\zlib\zlib-1.2.11\Release --with-extra-includes=c:\build-cache\zlib\zlib-1.2.11 --enable-debug-pack 2>&1'
+                $conf_cmd = 'call configure --with-xlswriter --with-extra-libs=c:\build-cache\libxlsxwriter\lib --with-extra-includes=c:\build-cache\libxlsxwriter\include --enable-debug-pack 2>&1'
                 echo $conf_cmd | Out-File -Encoding "ASCII" -Append task.bat
                 echo "nmake /nologo 2>&1" | Out-File -Encoding "ASCII" -Append task.bat
                 echo "exit %errorlevel%" | Out-File -Encoding "ASCII" -Append task.bat
@@ -152,7 +165,7 @@ after_build:
                 if ('x64' -eq $env:ARCH) { $dir = $dir + 'x64\' }
                 $dir = $dir + 'Release'
                 if ('1' -eq $env:TS) { $dir = $dir + '_TS' }
-                & 7z a c:\$zip_bname $dir\php_xlswriter.dll c:\projects\xlswriter\LICENSE
+                & 7z a c:\$zip_bname $dir\php_xlswriter.dll c:\projects\xlswriter\LICENSE c:\build-cache\libxlsxwriter\lib\xlsxwriter.lib c:\build-cache\libxlsxwriter\lib\xlsxwriter.pdb
                 Push-AppveyorArtifact c:\$zip_bname
 
 test_script:
@@ -173,7 +186,7 @@ test_script:
                 cd c:\projects\xlswriter
                 echo "" | Out-File -Encoding "ASCII" task.bat
                 echo "set REPORT_EXIT_STATUS=1" | Out-File -Encoding "ASCII" -Append task.bat
-                $cmd = 'call configure --with-xlswriter --with-xlswriter --with-extra-libs=c:\build-cache\zlib\zlib-1.2.11\Release --with-extra-includes=c:\build-cache\zlib\zlib-1.2.11 --with-prefix=c:\build-cache\' + $dname + ' 2>&1'
+                $cmd = 'call configure --with-xlswriter --with-extra-libs=c:\build-cache\libxlsxwriter\lib --with-extra-includes=c:\build-cache\libxlsxwriter\include --with-prefix=c:\build-cache\' + $dname + ' 2>&1'
                 echo $cmd | Out-File -Encoding "ASCII" -Append task.bat
                 echo 'nmake /nologo test TESTS="-q --show-diff --set-timeout 120" 2>&1' | Out-File -Encoding "ASCII" -Append task.bat
                 echo "exit %errorlevel%" | Out-File -Encoding "ASCII" -Append task.bat

+ 4 - 0
.gitmodules

@@ -0,0 +1,4 @@
+[submodule "library"]
+	path = library
+	url = https://github.com/jmcnamara/libxlsxwriter.git
+	branch = RELEASE_0.7.9

+ 1 - 0
.travis.yml

@@ -17,6 +17,7 @@ notifications:
   email: [email protected]
 
 before_script:
+  - git submodule update --init
   - sudo apt-get install zlib1g-dev -y
   - phpize && ./configure && make clean && make
 

+ 184 - 0
backup/.appveyor.yml.backup

@@ -0,0 +1,184 @@
+version: "{branch}.build.{build}"
+skip_tags: true
+
+branches:
+        only:
+                - master
+                - dev
+
+clone_folder:  c:\projects\xlswriter
+
+install:
+        ps: |
+                if (-not (Test-Path c:\build-cache)) {
+                        mkdir c:\build-cache
+                }
+                $bname = 'php-sdk-' + $env:BIN_SDK_VER + '.zip'
+                if (-not (Test-Path c:\build-cache\$bname)) {
+                        Invoke-WebRequest "https://github.com/OSTC/php-sdk-binary-tools/archive/$bname" -OutFile "c:\build-cache\$bname"
+                }
+                $dname0 = 'php-sdk-binary-tools-php-sdk-' + $env:BIN_SDK_VER
+                $dname1 = 'php-sdk-' + $env:BIN_SDK_VER
+                if (-not (Test-Path c:\build-cache\$dname1)) {
+                        7z x c:\build-cache\$bname -oc:\build-cache
+                        move c:\build-cache\$dname0 c:\build-cache\$dname1
+                }
+                $lname2 = 'zlib-1.2.11.tar.gz'
+                $lname3 = 'zlib'
+                if (-not (Test-Path c:\build-cache\$lname2)) {
+                        $zliurl = "http://zlib.net/" + $lname2
+                        Invoke-WebRequest $zliurl -OutFile "c:\build-cache\$lname2"
+                }
+                if (-not (Test-Path c:\build-cache\$lname3)) {
+                        & 7z x c:\build-cache\$lname2 -oc:\build-cache
+                        & 7z x c:\build-cache\zlib-1.2.11.tar -oc:\build-cache\$lname3
+                }
+                if (-not (Test-Path c:\build-cache\$lname3\Release)) {
+                       cd c:\build-cache\$lname3\zlib-1.2.11
+                       $cmakegen = 'Visual Studio 15 2017'
+                       if ($env:VC -Match "vc14") {
+                              $cmakegen = "Visual Studio 14 2015"
+                       }
+                       & cmake -G $cmakegen -DCMAKE_BUILD_TYPE="Release" -DCMAKE_C_FLAGS_RELEASE="/MT"
+                       & cmake --build . --config "Release"
+                }
+
+cache:
+        c:\build-cache -> .appveyor.yml
+
+environment:
+        BIN_SDK_VER: 2.1.2
+        LIBXLSXWRITER_VER: 0.7.7
+        matrix:
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x64
+                  VC: vc14
+                  PHP_VER: 7.0.28
+                  TS: 0
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x64
+                  VC: vc14
+                  PHP_VER: 7.0.28
+                  TS: 1
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x86
+                  VC: vc14
+                  PHP_VER: 7.0.28
+                  TS: 0
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x86
+                  VC: vc14
+                  PHP_VER: 7.0.28
+                  TS: 1
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x64
+                  VC: vc14
+                  PHP_VER: 7.1.15
+                  TS: 0
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x64
+                  VC: vc14
+                  PHP_VER: 7.1.15
+                  TS: 1
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x86
+                  VC: vc14
+                  PHP_VER: 7.1.15
+                  TS: 0
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+                  ARCH: x86
+                  VC: vc14
+                  PHP_VER: 7.1.15
+                  TS: 1
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+                  ARCH: x64
+                  VC: vc15
+                  PHP_VER: 7.2.3
+                  TS: 0
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+                  ARCH: x64
+                  VC: vc15
+                  PHP_VER: 7.2.3
+                  TS: 1
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+                  ARCH: x86
+                  VC: vc15
+                  PHP_VER: 7.2.3
+                  TS: 0
+                - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+                  ARCH: x86
+                  VC: vc15
+                  PHP_VER: 7.2.3
+                  TS: 1
+
+build_script:
+        ps: |
+                $ts_part = ''
+                if ('0' -eq $env:TS) { $ts_part = '-nts' }
+                $bname = 'php-devel-pack-' + $env:PHP_VER + $ts_part + '-Win32-' + $env:VC.toUpper() + '-' + $env:ARCH + '.zip'
+                if (-not (Test-Path c:\build-cache\$bname)) {
+                        Invoke-WebRequest "http://windows.php.net/downloads/releases/archives/$bname" -OutFile "c:\build-cache\$bname"
+                        if (-not (Test-Path c:\build-cache\$bname)) {
+                                Invoke-WebRequest "http://windows.php.net/downloads/releases/$bname" -OutFile "c:\build-cache\$bname"
+                        }
+                }
+                $dname0 = 'php-' + $env:PHP_VER + '-devel-' + $env:VC.toUpper() + '-' + $env:ARCH
+                $dname1 = 'php-' + $env:PHP_VER + $ts_part + '-devel-' + $env:VC.toUpper() + '-' + $env:ARCH
+                if (-not (Test-Path c:\build-cache\$dname1)) {
+                        7z x c:\build-cache\$bname -oc:\build-cache
+                        move c:\build-cache\$dname0 c:\build-cache\$dname1
+                }
+                cd c:\projects\xlswriter
+                $env:PATH = 'c:\build-cache\' + $dname1 + ';' + $env:PATH
+                #echo "@echo off" | Out-File -Encoding "ASCII" task.bat
+                #echo "" | Out-File -Encoding "ASCII" -Append task.bat
+                echo "" | Out-File -Encoding "ASCII" task.bat
+                echo "call git submodule update --init 2>&1" | Out-File -Encoding "ASCII" -Append task.bat
+                echo "call phpize 2>&1" | Out-File -Encoding "ASCII" -Append task.bat
+                $conf_cmd = 'call configure --with-xlswriter --with-extra-libs=c:\build-cache\zlib\zlib-1.2.11\Release --with-extra-includes=c:\build-cache\zlib\zlib-1.2.11 --enable-debug-pack 2>&1'
+                echo $conf_cmd | Out-File -Encoding "ASCII" -Append task.bat
+                echo "nmake /nologo 2>&1" | Out-File -Encoding "ASCII" -Append task.bat
+                echo "exit %errorlevel%" | Out-File -Encoding "ASCII" -Append task.bat
+                $here = (Get-Item -Path "." -Verbose).FullName
+                $runner = 'c:\build-cache\php-sdk-' + $env:BIN_SDK_VER + '\phpsdk' + '-' + $env:VC + '-' + $env:ARCH + '.bat'
+                $task = $here + '\task.bat'
+                & $runner -t $task
+
+after_build:
+        ps: |
+                $ts_part = 'ts'
+                if ('0' -eq $env:TS) { $ts_part = 'nts' }
+                $zip_bname = 'php_xlswriter-' + $env:APPVEYOR_REPO_COMMIT.substring(0, 8) + '-' + $env:PHP_VER.substring(0, 3) + '-' + $ts_part + '-' + $env:VC + '-' + $env:ARCH + '.zip'
+                $dir = 'c:\projects\xlswriter\';
+                if ('x64' -eq $env:ARCH) { $dir = $dir + 'x64\' }
+                $dir = $dir + 'Release'
+                if ('1' -eq $env:TS) { $dir = $dir + '_TS' }
+                & 7z a c:\$zip_bname $dir\php_xlswriter.dll c:\projects\xlswriter\LICENSE
+                Push-AppveyorArtifact c:\$zip_bname
+
+test_script:
+        ps: |
+                $ts_part = ''
+                if ('0' -eq $env:TS) { $ts_part = '-nts' }
+                $bname = 'php-' + $env:PHP_VER + $ts_part + '-Win32-' + $env:VC.toUpper() + '-' + $env:ARCH + '.zip'
+                if (-not (Test-Path c:\build-cache\$bname)) {
+                        Invoke-WebRequest "http://windows.php.net/downloads/releases/archives/$bname" -OutFile "c:\build-cache\$bname"
+                        if (-not (Test-Path c:\build-cache\$bname)) {
+                                Invoke-WebRequest "http://windows.php.net/downloads/releases/$bname" -OutFile "c:\build-cache\$bname"
+                        }
+                }
+                $dname = 'php-' + $env:PHP_VER + $ts_part + '-' + $env:VC.toUpper() + '-' + $env:ARCH
+                if (-not (Test-Path c:\build-cache\$dname)) {
+                        7z x c:\build-cache\$bname -oc:\build-cache\$dname
+                }
+                cd c:\projects\xlswriter
+                echo "" | Out-File -Encoding "ASCII" task.bat
+                echo "set REPORT_EXIT_STATUS=1" | Out-File -Encoding "ASCII" -Append task.bat
+                $cmd = 'call configure --with-xlswriter --with-xlswriter --with-extra-libs=c:\build-cache\zlib\zlib-1.2.11\Release --with-extra-includes=c:\build-cache\zlib\zlib-1.2.11 --with-prefix=c:\build-cache\' + $dname + ' 2>&1'
+                echo $cmd | Out-File -Encoding "ASCII" -Append task.bat
+                echo 'nmake /nologo test TESTS="-q --show-diff --set-timeout 120" 2>&1' | Out-File -Encoding "ASCII" -Append task.bat
+                echo "exit %errorlevel%" | Out-File -Encoding "ASCII" -Append task.bat
+                $here = (Get-Item -Path "." -Verbose).FullName
+                $runner = 'c:\build-cache\php-sdk-' + $env:BIN_SDK_VER + '\phpsdk' + '-' + $env:VC + '-' + $env:ARCH + '.bat'
+                $task = $here + '\task.bat'
+                & $runner -t $task

+ 28 - 0
backup/config.w32.backup

@@ -0,0 +1,28 @@
+// vim:ft=javascript
+
+ARG_WITH("xlswriter", "xlswriter support", "no");
+
+if (PHP_XLSWRITER != "no") {
+
+    MESSAGE("Include Path:" + configure_module_dirname + "\\include");
+
+    if (CHECK_LIB("zlib_a.lib;zlib.lib", "zlib", PHP_XLSWRITER) &&
+		CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS_XLSWRITER", "..\\zlib;" + php_usual_include_suspects) &&
+        CHECK_HEADER_ADD_INCLUDE("xlsxwriter.h", "CFLAGS_XLSWRITER", PHP_XLSWRITER + ";" + configure_module_dirname + "\\library\\include") &&
+		CHECK_HEADER_ADD_INCLUDE("packager.h", "CFLAGS_XLSWRITER", PHP_XLSWRITER + ";" + configure_module_dirname + "\\library\\include\\xlsxwriter") &&
+		CHECK_HEADER_ADD_INCLUDE("zip.h", "CFLAGS_XLSWRITER", PHP_XLSWRITER + ";" + configure_module_dirname + "\\library\\include\\xlsxwriter\\third_party")) {
+
+		EXTENSION("xlswriter", "xls_writer.c");
+
+        ADD_SOURCES(configure_module_dirname + "\\library\\third_party\\minizip", "ioapi.c iowin32.c mztools.c unzip.c zip.c", "xlswriter");
+        ADD_SOURCES(configure_module_dirname + "\\library\\third_party\\tmpfileplus", "tmpfileplus.c", "xlswriter");
+        ADD_SOURCES(configure_module_dirname + "\\library\\src", "app.c chart.c content_types.c core.c custom.c drawing.c format.c hash_table.c packager.c relationships.c shared_strings.c styles.c theme.c utility.c workbook.c worksheet.c xmlwriter.c", "xlswriter");
+        ADD_SOURCES(configure_module_dirname + "\\kernel", "common.c resource.c exception.c excel.c write.c format.c", "xlswriter");
+
+		ADD_FLAG("CFLAGS_XLSWRITER", ' /I "' + configure_module_dirname + '" ');
+
+    } else {
+        WARNING("xlswriter not enabled, headers not found");
+    }
+
+}

+ 10 - 4
config.m4

@@ -26,7 +26,7 @@ if test "$PHP_XLSWRITER" != "no"; then
     library/src/core.c \
     library/src/custom.c \
     library/src/drawing.c \
-    library/src/xlsx_format.c \
+    library/src/format.c \
     library/src/hash_table.c \
     library/src/packager.c \
     library/src/relationships.c \
@@ -82,9 +82,15 @@ if test "$PHP_XLSWRITER" != "no"; then
         xls_writer_sources="$xls_writer_sources $libxlsxwriter_sources"
         PHP_ADD_INCLUDE([$srcdir/library/include])
 
-        dnl uncomment when bunled lib will be updated
-        dnl AC_DEFINE(HAVE_LXW_VERSION, 1, [ lxw_version available in 0.7.9 ])
-        dnl AC_DEFINE(HAVE_LXW_CHARTSHEET_NEW, 1, [ lxw_chartsheet_new available in 0.8.0 ])
+        XLSXWRITER_VERSION=`$EGREP "define LXW_VERSION" $srcdir/library/include/xlsxwriter.h | $SED -e 's/[[^0-9\.]]//g'`
+
+        if test `echo $XLSXWRITER_VERSION | $SED -e 's/[[^0-9]]/ /g' | $AWK '{print $1*10000 + $2*100 + $3}'` -lt 800; then
+            AC_DEFINE(HAVE_LXW_VERSION, 1, [ lxw_version available in 0.7.9 ])
+        fi
+
+        if test `echo $XLSXWRITER_VERSION | $SED -e 's/[[^0-9]]/ /g' | $AWK '{print $1*10000 + $2*100 + $3}'` -ge 800; then
+            AC_DEFINE(HAVE_LXW_CHARTSHEET_NEW, 1, [ lxw_chartsheet_new available in 0.8.0 ])
+        fi
     fi
 
     if test -z "$PHP_DEBUG"; then

+ 7 - 17
config.w32

@@ -4,25 +4,15 @@ ARG_WITH("xlswriter", "xlswriter support", "no");
 
 if (PHP_XLSWRITER != "no") {
 
-    MESSAGE("Include Path:" + configure_module_dirname + "\\include");
-
-    if (CHECK_LIB("zlib_a.lib;zlib.lib", "zlib", PHP_XLSWRITER) &&
-		CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS_XLSWRITER", "..\\zlib;" + php_usual_include_suspects) &&
-        CHECK_HEADER_ADD_INCLUDE("xlsxwriter.h", "CFLAGS_XLSWRITER", PHP_XLSWRITER + ";" + configure_module_dirname + "\\library\\include") &&
-		CHECK_HEADER_ADD_INCLUDE("packager.h", "CFLAGS_XLSWRITER", PHP_XLSWRITER + ";" + configure_module_dirname + "\\library\\include\\xlsxwriter") &&
-		CHECK_HEADER_ADD_INCLUDE("zip.h", "CFLAGS_XLSWRITER", PHP_XLSWRITER + ";" + configure_module_dirname + "\\library\\include\\xlsxwriter\\third_party")) {
-
-		EXTENSION("xlswriter", "xls_writer.c");
-
-        ADD_SOURCES(configure_module_dirname + "\\library\\third_party\\minizip", "ioapi.c iowin32.c mztools.c unzip.c zip.c", "xlswriter");
-        ADD_SOURCES(configure_module_dirname + "\\library\\third_party\\tmpfileplus", "tmpfileplus.c", "xlswriter");
-        ADD_SOURCES(configure_module_dirname + "\\library\\src", "app.c chart.c content_types.c core.c custom.c drawing.c xlsx_format.c hash_table.c packager.c relationships.c shared_strings.c styles.c theme.c utility.c workbook.c worksheet.c xmlwriter.c", "xlswriter");
+    if (CHECK_LIB("xlsxwriter.lib;xlsxwriter_a.lib", "xlswriter", PHP_XLSWRITER) &&
+        CHECK_HEADER_ADD_INCLUDE("xlsxwriter.h", "CFLAGS_XLSWRITER", PHP_PHP_BUILD + "\\include;" + PHP_XLSWRITER) &&
+        CHECK_HEADER_ADD_INCLUDE("xlsxwriter/packager.h", "CFLAGS_XLSWRITER", PHP_PHP_BUILD + "\\include;" + PHP_XLSWRITER) &&
+        CHECK_HEADER_ADD_INCLUDE("xlsxwriter/format.h", "CFLAGS_XLSWRITER", PHP_PHP_BUILD + "\\include;" + PHP_XLSWRITER)) {
+        EXTENSION("xlswriter", "xls_writer.c")
+        AC_DEFINE("HAVE_LXW_VERSION", 1, "lxw_version available in 0.7.7");
         ADD_SOURCES(configure_module_dirname + "\\kernel", "common.c resource.c exception.c excel.c write.c format.c", "xlswriter");
-
-		ADD_FLAG("CFLAGS_XLSWRITER", ' /I "' + configure_module_dirname + '" ');
-
     } else {
-        WARNING("xlswriter not enabled, headers not found");
+        WARNING("xlswriter not enabled, xlsxwriter.lib or headers not found");
     }
 
 }

+ 1 - 0
library

@@ -0,0 +1 @@
+Subproject commit f59bdffe692e97789ff570d08aae20cb6e4781a9

+ 0 - 150
library/License.txt

@@ -1,150 +0,0 @@
-/**
-
-@page license License
-
-Libxlsxwriter is released under a FreeBSD license:
-
-    Copyright 2014-2018, John McNamara <[email protected]>
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are
-    met:
-
-    1. Redistributions of source code must retain the above copyright notice,
-       this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    The views and conclusions contained in the software and documentation are
-    those of the authors and should not be interpreted as representing
-    official policies, either expressed or implied, of the FreeBSD Project.
-
-
-Libxlsxwriter includes `queue.h` and `tree.h` from FreeBSD, the `minizip`
-component of `zlib` and `tmpfileplus` which have the following licenses:
-
-
-Queue.h from FreeBSD:
-
-    Copyright (c) 1991, 1993
-     The Regents of the University of California.  All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    4. Neither the name of the University nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-
-Tree.h from FreeBSD:
-
-    Copyright 2002 Niels Provos <[email protected]>
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-
-    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-The `minizip` files used in the libxlsxwriter source tree are taken from the
-`zlib` ` contrib/minizip` directory. [Zlib](http://www.zlib.net) has the
-following License/Copyright:
-
-    (C) 1995-2013 Jean-loup Gailly and Mark Adler
-
-    This software is provided 'as-is', without any express or implied
-    warranty.  In no event will the authors be held liable for any damages
-    arising from the use of this software.
-
-    Permission is granted to anyone to use this software for any purpose,
-    including commercial applications, and to alter it and redistribute it
-    freely, subject to the following restrictions:
-
-    1. The origin of this software must not be misrepresented; you must not
-       claim that you wrote the original software. If you use this software
-       in a product, an acknowledgment in the product documentation would be
-       appreciated but is not required.
-    2. Altered source versions must be plainly marked as such, and must not be
-       misrepresented as being the original software.
-    3. This notice may not be removed or altered from any source distribution.
-
-    Jean-loup Gailly        Mark Adler
-    [email protected]          [email protected]
-
-The `minizip` files have the following additional copyright declarations:
-
-    Copyright (C) 1998-2010 Gilles Vollant
-    (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-    Modifications for Zip64 support
-    Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-Note, it is possible to compile libxlsxwriter without statically linking the
-`minizip` files and instead dynamically linking to `lminizip`, see
-@ref gsg_minizip.
-
-[Tmpfileplus](http://www.di-mgt.com.au/c_function_to_create_temp_file.html)
-has the following license:
-
-     This Source Code Form is subject to the terms of the Mozilla Public
-     License, v. 2.0. If a copy of the MPL was not distributed with this
-     file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-     Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
-     <http://www.di-mgt.com.au/contact/>.
-
-See the [Mozilla Public License, v. 2.0](http://mozilla.org/MPL/2.0/).
-
-Note, it is possible to compile libxlsxwriter using the standard library
-`tmpfile()` function instead of `tmpfileplus`, see @ref gsg_tmpdir.
-
-Next: @ref changes
-*/

+ 0 - 131
library/include/crypt.h

@@ -1,131 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
-   Version 1.01e, February 12th, 2005
-
-   Copyright (C) 1998-2005 Gilles Vollant
-
-   This code is a modified version of crypting code in Infozip distribution
-
-   The encryption/decryption parts of this source code (as opposed to the
-   non-echoing password parts) were originally written in Europe.  The
-   whole source package can be freely distributed, including from the USA.
-   (Prior to January 2000, re-export from the US was a violation of US law.)
-
-   This encryption code is a direct transcription of the algorithm from
-   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
-   file (appnote.txt) is distributed with the PKZIP program (even in the
-   version without encryption capabilities).
-
-   If you don't need crypting in your application, just define symbols
-   NOCRYPT and NOUNCRYPT.
-
-   This code support the "Traditional PKWARE Encryption".
-
-   The new AES encryption added on Zip format by Winzip (see the page
-   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
-   Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
-{
-    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
-                     * unpredictable manner on 16-bit systems; not a problem
-                     * with any known compiler so far, though */
-
-    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
-    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
-{
-    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
-    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
-    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
-    {
-      register int keyshift = (int)((*(pkeys+1)) >> 24);
-      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
-    }
-    return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
-{
-    *(pkeys+0) = 305419896L;
-    *(pkeys+1) = 591751049L;
-    *(pkeys+2) = 878082192L;
-    while (*passwd != '\0') {
-        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
-        passwd++;
-    }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
-    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
-    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN  12
-   /* "last resort" source for second part of crypt seed pattern */
-#  ifndef ZCR_SEED2
-#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
-#  endif
-
-static int crypthead(const char* passwd,      /* password string */
-                     unsigned char* buf,      /* where to write header */
-                     int bufSize,
-                     unsigned long* pkeys,
-                     const z_crc_t* pcrc_32_tab,
-                     unsigned long crcForCrypting)
-{
-    int n;                       /* index in random header */
-    int t;                       /* temporary */
-    int c;                       /* random byte */
-    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
-    static unsigned calls = 0;   /* ensure different random header each time */
-
-    if (bufSize<RAND_HEAD_LEN)
-      return 0;
-
-    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
-     * output of rand() to get less predictability, since rand() is
-     * often poorly implemented.
-     */
-    if (++calls == 1)
-    {
-        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
-    }
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        c = (rand() >> 7) & 0xff;
-        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
-    }
-    /* Encrypt random header (last two bytes is high word of crc) */
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
-    }
-    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
-    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
-    return n;
-}
-
-#endif

+ 0 - 208
library/include/ioapi.h

@@ -1,208 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         Changes
-
-    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
-    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
-               More if/def section may be needed to support other platforms
-    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
-                          (but you should use iowin32.c for windows instead)
-
-*/
-
-#ifndef _ZLIBIOAPI64_H
-#define _ZLIBIOAPI64_H
-
-#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
-
-  // Linux needs this to support file operation on files larger then 4+GB
-  // But might need better if/def to select just the platforms that needs them.
-
-        #ifndef __USE_FILE_OFFSET64
-                #define __USE_FILE_OFFSET64
-        #endif
-        #ifndef __USE_LARGEFILE64
-                #define __USE_LARGEFILE64
-        #endif
-        #ifndef _LARGEFILE64_SOURCE
-                #define _LARGEFILE64_SOURCE
-        #endif
-        #ifndef _FILE_OFFSET_BIT
-                #define _FILE_OFFSET_BIT 64
-        #endif
-
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "zlib.h"
-
-#if defined(USE_FILE32API)
-#define fopen64 fopen
-#define ftello64 ftell
-#define fseeko64 fseek
-#else
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#define fopen64 fopen
-#define ftello64 ftello
-#define fseeko64 fseeko
-#endif
-#ifdef _MSC_VER
- #define fopen64 fopen
- #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
-  #define ftello64 _ftelli64
-  #define fseeko64 _fseeki64
- #else // old MSC
-  #define ftello64 ftell
-  #define fseeko64 fseek
- #endif
-#endif
-#endif
-
-/*
-#ifndef ZPOS64_T
-  #ifdef _WIN32
-                #define ZPOS64_T fpos_t
-  #else
-    #include <stdint.h>
-    #define ZPOS64_T uint64_t
-  #endif
-#endif
-*/
-
-#ifdef HAVE_MINIZIP64_CONF_H
-#include "mz64conf.h"
-#endif
-
-/* a type choosen by DEFINE */
-#ifdef HAVE_64BIT_INT_CUSTOM
-typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
-#else
-#ifdef HAS_STDINT_H
-#include "stdint.h"
-typedef uint64_t ZPOS64_T;
-#else
-
-/* Maximum unsigned 32-bit value used as placeholder for zip64 */
-#define MAXU32 0xffffffff
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 ZPOS64_T;
-#else
-typedef unsigned long long int ZPOS64_T;
-#endif
-#endif
-#endif
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ      (1)
-#define ZLIB_FILEFUNC_MODE_WRITE     (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE   (8)
-
-
-#ifndef ZCALLBACK
- #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-   #define ZCALLBACK CALLBACK
- #else
-   #define ZCALLBACK
- #endif
-#endif
-
-
-
-
-typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
-typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
-typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-
-
-/* here is the "old" 32 bits structure structure */
-typedef struct zlib_filefunc_def_s
-{
-    open_file_func      zopen_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell_file_func      ztell_file;
-    seek_file_func      zseek_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc_def;
-
-typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
-
-typedef struct zlib_filefunc64_def_s
-{
-    open64_file_func    zopen64_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell64_file_func    ztell64_file;
-    seek64_file_func    zseek64_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc64_def;
-
-void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-/* now internal definition, only for zip.c and unzip.h */
-typedef struct zlib_filefunc64_32_def_s
-{
-    zlib_filefunc64_def zfile_func64;
-    open_file_func      zopen32_file;
-    tell_file_func      ztell32_file;
-    seek_file_func      zseek32_file;
-} zlib_filefunc64_32_def;
-
-
-#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
-#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
-/* #define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) */
-/* #define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) */
-#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
-#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
-
-voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
-long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
-ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
-
-void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
-
-#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
-#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
-#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 28
library/include/iowin32.h

@@ -1,28 +0,0 @@
-/* iowin32.h -- IO base function header for compress/uncompress .zip
-     Version 1.1, February 14h, 2010
-     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-*/
-
-#include <windows.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 37
library/include/mztools.h

@@ -1,37 +0,0 @@
-/*
-  Additional tools for Minizip
-  Code: Xavier Roche '2004
-  License: Same as ZLIB (www.gzip.org)
-*/
-
-#ifndef _zip_tools_H
-#define _zip_tools_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#include "unzip.h"
-
-/* Repair a ZIP file (missing central directory)
-   file: file to recover
-   fileOut: output file after recovery
-   fileOutTmp: temporary file name used for recovery
-*/
-extern int ZEXPORT unzRepair(const char* file,
-                             const char* fileOut,
-                             const char* fileOutTmp,
-                             uLong* nRecovered,
-                             uLong* bytesRecovered);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif

+ 0 - 53
library/include/tmpfileplus.h

@@ -1,53 +0,0 @@
-/* $Id: tmpfileplus.h $ */
-/*
- * $Date: 2016-06-01 03:31Z $
- * $Revision: 2.0.0 $
- * $Author: dai $
- */
-
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
- * <http://www.di-mgt.com.au/contact/>.
- */
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifndef TMPFILEPLUS_H_
-#define TMPFILEPLUS_H_
-
-#include <stdio.h>
-
-/** Create a unique temporary file.
-@param dir (optional) directory to create file. If NULL use default TMP directory.
-@param prefix (optional) prefix for file name. If NULL use "tmp.".
-@param pathname (optional) pointer to a buffer to receive the temp filename. 
-	Allocated using `malloc()`; user to free. Ignored if NULL.
-@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 
-	Otherwise file is automatically deleted when closed.
-@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
-@exception ENOMEM Not enough memory to allocate filename.
-*/
-FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
-
-
-/** Create a unique temporary file with filename stored in a fixed-length buffer.
-@param dir (optional) directory to create file. If NULL use default directory.
-@param prefix (optional) prefix for file name. If NULL use "tmp.".
-@param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL.
-@param pathsize Size of buffer to receive filename and its terminating null character.
-@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing.
-	Otherwise file is automatically deleted when closed.
-@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
-@exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
-*/
-FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
-
-#define TMPFILE_KEEP 1
-
-#endif /* end TMPFILEPLUS_H_ */

+ 0 - 437
library/include/unzip.h

@@ -1,437 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications of Unzip for Zip64
-         Copyright (C) 2007-2008 Even Rouault
-
-         Modifications for Zip64 support on both zip and unzip
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         ---------------------------------------------------------------------------------
-
-        Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  ---------------------------------------------------------------------------------
-
-        Changes
-
-        See header of unzip64.c
-
-*/
-
-#ifndef _unz64_H
-#define _unz64_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef  _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#ifdef HAVE_BZIP2
-#include "bzlib.h"
-#endif
-
-#define Z_BZIP2ED 12
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK                          (0)
-#define UNZ_END_OF_LIST_OF_FILE         (-100)
-#define UNZ_ERRNO                       (Z_ERRNO)
-#define UNZ_EOF                         (0)
-#define UNZ_PARAMERROR                  (-102)
-#define UNZ_BADZIPFILE                  (-103)
-#define UNZ_INTERNALERROR               (-104)
-#define UNZ_CRCERROR                    (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
-   These data comes from the end of central dir */
-typedef struct unz_global_info64_s
-{
-    ZPOS64_T number_entry;         /* total number of entries in
-                                     the central dir on this disk */
-    uLong size_comment;         /* size of the global comment of the zipfile */
-} unz_global_info64;
-
-typedef struct unz_global_info_s
-{
-    uLong number_entry;         /* total number of entries in
-                                     the central dir on this disk */
-    uLong size_comment;         /* size of the global comment of the zipfile */
-} unz_global_info;
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info64_s
-{
-    uLong version;              /* version made by                 2 bytes */
-    uLong version_needed;       /* version needed to extract       2 bytes */
-    uLong flag;                 /* general purpose bit flag        2 bytes */
-    uLong compression_method;   /* compression method              2 bytes */
-    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
-    uLong crc;                  /* crc-32                          4 bytes */
-    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */
-    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */
-    uLong size_filename;        /* filename length                 2 bytes */
-    uLong size_file_extra;      /* extra field length              2 bytes */
-    uLong size_file_comment;    /* file comment length             2 bytes */
-
-    uLong disk_num_start;       /* disk number start               2 bytes */
-    uLong internal_fa;          /* internal file attributes        2 bytes */
-    uLong external_fa;          /* external file attributes        4 bytes */
-
-    tm_unz tmu_date;
-} unz_file_info64;
-
-typedef struct unz_file_info_s
-{
-    uLong version;              /* version made by                 2 bytes */
-    uLong version_needed;       /* version needed to extract       2 bytes */
-    uLong flag;                 /* general purpose bit flag        2 bytes */
-    uLong compression_method;   /* compression method              2 bytes */
-    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
-    uLong crc;                  /* crc-32                          4 bytes */
-    uLong compressed_size;      /* compressed size                 4 bytes */
-    uLong uncompressed_size;    /* uncompressed size               4 bytes */
-    uLong size_filename;        /* filename length                 2 bytes */
-    uLong size_file_extra;      /* extra field length              2 bytes */
-    uLong size_file_comment;    /* file comment length             2 bytes */
-
-    uLong disk_num_start;       /* disk number start               2 bytes */
-    uLong internal_fa;          /* internal file attributes        2 bytes */
-    uLong external_fa;          /* external file attributes        4 bytes */
-
-    tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
-                                                 const char* fileName2,
-                                                 int iCaseSensitivity));
-/*
-   Compare two filename (fileName1,fileName2).
-   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
-   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
-                                or strcasecmp)
-   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
-    (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-extern unzFile ZEXPORT unzOpen64 OF((const void *path));
-/*
-  Open a Zip file. path contain the full pathname (by example,
-     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
-     "zlib/zlib113.zip".
-     If the zipfile cannot be opened (file don't exist or in not valid), the
-       return value is NULL.
-     Else, the return value is a unzFile Handle, usable with other function
-       of this unzip package.
-     the "64" function take a const void* pointer, because the path is just the
-       value passed to the open64_file_func callback.
-     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
-       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
-       does not describe the reality
-*/
-
-
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
-                                    zlib_filefunc_def* pzlib_filefunc_def));
-/*
-   Open a Zip file, like unzOpen, but provide a set of file low level API
-      for read/write the zip file (see ioapi.h)
-*/
-
-extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
-                                    zlib_filefunc64_def* pzlib_filefunc_def));
-/*
-   Open a Zip file, like unz64Open, but provide a set of file low level API
-      for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
-  Close a ZipFile opened with unzOpen.
-  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
-    these files MUST be closed with unzCloseCurrentFile before call unzClose.
-  return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
-                                        unz_global_info *pglobal_info));
-
-extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
-                                        unz_global_info64 *pglobal_info));
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
-                                           char *szComment,
-                                           uLong uSizeBuf));
-/*
-  Get the global comment string of the ZipFile, in the szComment buffer.
-  uSizeBuf is the size of the szComment buffer.
-  return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
-  Set the current file of the zipfile to the first file.
-  return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
-  Set the current file of the zipfile to the next file.
-  return UNZ_OK if there is no problem
-  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
-                     const char *szFileName,
-                     int iCaseSensitivity));
-/*
-  Try locate the file szFileName in the zipfile.
-  For the iCaseSensitivity signification, see unzStringFileNameCompare
-
-  return value :
-  UNZ_OK if the file is found. It becomes the current file.
-  UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
-    uLong pos_in_zip_directory;   /* offset in zip file directory */
-    uLong num_of_file;            /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
-    unzFile file,
-    unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
-    unzFile file,
-    unz_file_pos* file_pos);
-
-typedef struct unz64_file_pos_s
-{
-    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */
-    ZPOS64_T num_of_file;            /* # of file */
-} unz64_file_pos;
-
-extern int ZEXPORT unzGetFilePos64(
-    unzFile file,
-    unz64_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos64(
-    unzFile file,
-    const unz64_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
-                         unz_file_info64 *pfile_info,
-                         char *szFileName,
-                         uLong fileNameBufferSize,
-                         void *extraField,
-                         uLong extraFieldBufferSize,
-                         char *szComment,
-                         uLong commentBufferSize));
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
-                         unz_file_info *pfile_info,
-                         char *szFileName,
-                         uLong fileNameBufferSize,
-                         void *extraField,
-                         uLong extraFieldBufferSize,
-                         char *szComment,
-                         uLong commentBufferSize));
-/*
-  Get Info about the current file
-  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
-        the current file
-  if szFileName!=NULL, the filemane string will be copied in szFileName
-            (fileNameBufferSize is the size of the buffer)
-  if extraField!=NULL, the extra field information will be copied in extraField
-            (extraFieldBufferSize is the size of the buffer).
-            This is the Central-header version of the extra field
-  if szComment!=NULL, the comment string of the file will be copied in szComment
-            (commentBufferSize is the size of the buffer)
-*/
-
-
-/** Addition for GDAL : START */
-
-extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
-
-/** Addition for GDAL : END */
-
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
-   from it, and close it (you can close it before reading all the file)
-   */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
-  Open for reading data the current file in the zipfile.
-  If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
-                                                  const char* password));
-/*
-  Open for reading data the current file in the zipfile.
-  password is a crypting password
-  If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
-                                           int* method,
-                                           int* level,
-                                           int raw));
-/*
-  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
-    if raw==1
-  *method will receive method of compression, *level will receive level of
-     compression
-  note : you can set level parameter as NULL (if you did not want known level,
-         but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
-                                           int* method,
-                                           int* level,
-                                           int raw,
-                                           const char* password));
-/*
-  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
-    if raw==1
-  *method will receive method of compression, *level will receive level of
-     compression
-  note : you can set level parameter as NULL (if you did not want known level,
-         but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
-  Close the file in zip opened with unzOpenCurrentFile
-  Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
-                      voidp buf,
-                      unsigned len));
-/*
-  Read bytes from the current file (opened by unzOpenCurrentFile)
-  buf contain buffer where data must be copied
-  len the size of buf.
-
-  return the number of byte copied if somes bytes are copied
-  return 0 if the end of file was reached
-  return <0 with error code if there is an error
-    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-
-extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
-/*
-  Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
-  return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
-                                             voidp buf,
-                                             unsigned len));
-/*
-  Read extra field from the current file (opened by unzOpenCurrentFile)
-  This is the local-header version of the extra field (sometimes, there is
-    more info in the local-header version than in the central-header)
-
-  if buf==NULL, it return the size of the local extra field
-
-  if buf!=NULL, len is the size of the buffer, the extra header is copied in
-    buf.
-  the return value is the number of bytes copied in buf, or (if <0)
-    the error code
-*/
-
-/***************************************************************************/
-
-/* Get the current file offset */
-extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
-extern uLong ZEXPORT unzGetOffset (unzFile file);
-
-/* Set the current file offset */
-extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz64_H */

+ 0 - 23
library/include/xlsxwriter.h

@@ -1,23 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- */
-
-/**
- * @file xlsxwriter.h
- *
- * xlsxwriter - A library for creating Excel XLSX files.
- *
- */
-#ifndef __LXW_XLSXWRITER_H__
-#define __LXW_XLSXWRITER_H__
-
-#include "xlsxwriter/workbook.h"
-#include "xlsxwriter/worksheet.h"
-#include "xlsxwriter/format.h"
-#include "xlsxwriter/utility.h"
-
-#define LXW_VERSION "0.7.7"
-
-#endif /* __LXW_XLSXWRITER_H__ */

+ 0 - 79
library/include/xlsxwriter/app.h

@@ -1,79 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * app - A libxlsxwriter library for creating Excel XLSX app files.
- *
- */
-#ifndef __LXW_APP_H__
-#define __LXW_APP_H__
-
-#include <stdint.h>
-#include <string.h>
-#include "workbook.h"
-#include "common.h"
-
-/* Define the queue.h TAILQ structs for the App structs. */
-STAILQ_HEAD(lxw_heading_pairs, lxw_heading_pair);
-STAILQ_HEAD(lxw_part_names, lxw_part_name);
-
-typedef struct lxw_heading_pair {
-
-    char *key;
-    char *value;
-
-    STAILQ_ENTRY (lxw_heading_pair) list_pointers;
-
-} lxw_heading_pair;
-
-typedef struct lxw_part_name {
-
-    char *name;
-
-    STAILQ_ENTRY (lxw_part_name) list_pointers;
-
-} lxw_part_name;
-
-/* Struct to represent an App object. */
-typedef struct lxw_app {
-
-    FILE *file;
-
-    struct lxw_heading_pairs *heading_pairs;
-    struct lxw_part_names *part_names;
-    lxw_doc_properties *properties;
-
-    uint32_t num_heading_pairs;
-    uint32_t num_part_names;
-
-} lxw_app;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_app *lxw_app_new();
-void lxw_app_free(lxw_app *app);
-void lxw_app_assemble_xml_file(lxw_app *self);
-void lxw_app_add_part_name(lxw_app *self, const char *name);
-void lxw_app_add_heading_pair(lxw_app *self, const char *key,
-                              const char *value);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _app_xml_declaration(lxw_app *self);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_APP_H__ */

+ 0 - 3577
library/include/xlsxwriter/chart.h

@@ -1,3577 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * chart - A libxlsxwriter library for creating Excel XLSX chart files.
- *
- */
-
-/**
- * @page chart_page The Chart object
- *
- * The Chart object represents an Excel chart. It provides functions for
- * adding data series to the chart and for configuring the chart.
- *
- * See @ref chart.h for full details of the functionality.
- *
- * @file chart.h
- *
- * @brief Functions related to adding data to and configuring  a chart.
- *
- * The Chart object represents an Excel chart. It provides functions for
- * adding data series to the chart and for configuring the chart.
- *
- * A Chart object isn't created directly. Instead a chart is created by
- * calling the `workbook_add_chart()` function from a Workbook object. For
- * example:
- *
- * @code
- *
- * #include "xlsxwriter.h"
- *
- * int main() {
- *
- *     lxw_workbook  *workbook  = new_workbook("chart.xlsx");
- *     lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
- *
- *     // User function to add data to worksheet, not shown here.
- *     write_worksheet_data(worksheet);
- *
- *     // Create a chart object.
- *     lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
- *
- *     // In the simplest case we just add some value data series.
- *     // The NULL categories will default to 1 to 5 like in Excel.
- *     chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
- *     chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
- *     chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
- *
- *     // Insert the chart into the worksheet
- *     worksheet_insert_chart(worksheet, CELL("B7"), chart);
- *
- *     return workbook_close(workbook);
- * }
- *
- * @endcode
- *
- * The chart in the worksheet will look like this:
- * @image html chart_simple.png
- *
- * The basic procedure for adding a chart to a worksheet is:
- *
- * 1. Create the chart with `workbook_add_chart()`.
- * 2. Add one or more data series to the chart which refers to data in the
- *    workbook using `chart_add_series()`.
- * 3. Configure the chart with the other available functions shown below.
- * 4. Insert the chart into a worksheet using `worksheet_insert_chart()`.
- *
- */
-
-#ifndef __LXW_CHART_H__
-#define __LXW_CHART_H__
-
-#include <stdint.h>
-#include <string.h>
-
-#include "common.h"
-#include "format.h"
-
-STAILQ_HEAD(lxw_chart_series_list, lxw_chart_series);
-STAILQ_HEAD(lxw_series_data_points, lxw_series_data_point);
-
-#define LXW_CHART_NUM_FORMAT_LEN 128
-#define LXW_CHART_DEFAULT_GAP 501
-
-/**
- * @brief Available chart types.
- */
-typedef enum lxw_chart_type {
-
-    /** None. */
-    LXW_CHART_NONE = 0,
-
-    /** Area chart. */
-    LXW_CHART_AREA,
-
-    /** Area chart - stacked. */
-    LXW_CHART_AREA_STACKED,
-
-    /** Area chart - percentage stacked. */
-    LXW_CHART_AREA_STACKED_PERCENT,
-
-    /** Bar chart. */
-    LXW_CHART_BAR,
-
-    /** Bar chart - stacked. */
-    LXW_CHART_BAR_STACKED,
-
-    /** Bar chart - percentage stacked. */
-    LXW_CHART_BAR_STACKED_PERCENT,
-
-    /** Column chart. */
-    LXW_CHART_COLUMN,
-
-    /** Column chart - stacked. */
-    LXW_CHART_COLUMN_STACKED,
-
-    /** Column chart - percentage stacked. */
-    LXW_CHART_COLUMN_STACKED_PERCENT,
-
-    /** Doughnut chart. */
-    LXW_CHART_DOUGHNUT,
-
-    /** Line chart. */
-    LXW_CHART_LINE,
-
-    /** Pie chart. */
-    LXW_CHART_PIE,
-
-    /** Scatter chart. */
-    LXW_CHART_SCATTER,
-
-    /** Scatter chart - straight. */
-    LXW_CHART_SCATTER_STRAIGHT,
-
-    /** Scatter chart - straight with markers. */
-    LXW_CHART_SCATTER_STRAIGHT_WITH_MARKERS,
-
-    /** Scatter chart - smooth. */
-    LXW_CHART_SCATTER_SMOOTH,
-
-    /** Scatter chart - smooth with markers. */
-    LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS,
-
-    /** Radar chart. */
-    LXW_CHART_RADAR,
-
-    /** Radar chart - with markers. */
-    LXW_CHART_RADAR_WITH_MARKERS,
-
-    /** Radar chart - filled. */
-    LXW_CHART_RADAR_FILLED
-} lxw_chart_type;
-
-/**
- * @brief Chart legend positions.
- */
-typedef enum lxw_chart_legend_position {
-
-    /** No chart legend. */
-    LXW_CHART_LEGEND_NONE = 0,
-
-    /** Chart legend positioned at right side. */
-    LXW_CHART_LEGEND_RIGHT,
-
-    /** Chart legend positioned at left side. */
-    LXW_CHART_LEGEND_LEFT,
-
-    /** Chart legend positioned at top. */
-    LXW_CHART_LEGEND_TOP,
-
-    /** Chart legend positioned at bottom. */
-    LXW_CHART_LEGEND_BOTTOM,
-
-    /** Chart legend overlaid at right side. */
-    LXW_CHART_LEGEND_OVERLAY_RIGHT,
-
-    /** Chart legend overlaid at left side. */
-    LXW_CHART_LEGEND_OVERLAY_LEFT
-} lxw_chart_legend_position;
-
-/**
- * @brief Chart line dash types.
- *
- * The dash types are shown in the order that they appear in the Excel dialog.
- * See @ref chart_lines.
- */
-typedef enum lxw_chart_line_dash_type {
-
-    /** Solid. */
-    LXW_CHART_LINE_DASH_SOLID = 0,
-
-    /** Round Dot. */
-    LXW_CHART_LINE_DASH_ROUND_DOT,
-
-    /** Square Dot. */
-    LXW_CHART_LINE_DASH_SQUARE_DOT,
-
-    /** Dash. */
-    LXW_CHART_LINE_DASH_DASH,
-
-    /** Dash Dot. */
-    LXW_CHART_LINE_DASH_DASH_DOT,
-
-    /** Long Dash. */
-    LXW_CHART_LINE_DASH_LONG_DASH,
-
-    /** Long Dash Dot. */
-    LXW_CHART_LINE_DASH_LONG_DASH_DOT,
-
-    /** Long Dash Dot Dot. */
-    LXW_CHART_LINE_DASH_LONG_DASH_DOT_DOT,
-
-    /* These aren't available in the dialog but are used by Excel. */
-    LXW_CHART_LINE_DASH_DOT,
-    LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT,
-    LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT_DOT
-} lxw_chart_line_dash_type;
-
-/**
- * @brief Chart marker types.
- */
-typedef enum lxw_chart_marker_type {
-
-    /** Automatic, series default, marker type. */
-    LXW_CHART_MARKER_AUTOMATIC,
-
-    /** No marker type. */
-    LXW_CHART_MARKER_NONE,
-
-    /** Square marker type. */
-    LXW_CHART_MARKER_SQUARE,
-
-    /** Diamond marker type. */
-    LXW_CHART_MARKER_DIAMOND,
-
-    /** Triangle marker type. */
-    LXW_CHART_MARKER_TRIANGLE,
-
-    /** X shape marker type. */
-    LXW_CHART_MARKER_X,
-
-    /** Star marker type. */
-    LXW_CHART_MARKER_STAR,
-
-    /** Short dash marker type. */
-    LXW_CHART_MARKER_SHORT_DASH,
-
-    /** Long dash marker type. */
-    LXW_CHART_MARKER_LONG_DASH,
-
-    /** Circle marker type. */
-    LXW_CHART_MARKER_CIRCLE,
-
-    /** Plus (+) marker type. */
-    LXW_CHART_MARKER_PLUS
-} lxw_chart_marker_type;
-
-/**
- * @brief Chart pattern types.
- */
-typedef enum lxw_chart_pattern_type {
-
-    /** None pattern. */
-    LXW_CHART_PATTERN_NONE,
-
-    /** 5 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_5,
-
-    /** 10 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_10,
-
-    /** 20 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_20,
-
-    /** 25 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_25,
-
-    /** 30 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_30,
-
-    /** 40 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_40,
-
-    /** 50 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_50,
-
-    /** 60 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_60,
-
-    /** 70 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_70,
-
-    /** 75 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_75,
-
-    /** 80 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_80,
-
-    /** 90 Percent pattern. */
-    LXW_CHART_PATTERN_PERCENT_90,
-
-    /** Light downward diagonal pattern. */
-    LXW_CHART_PATTERN_LIGHT_DOWNWARD_DIAGONAL,
-
-    /** Light upward diagonal pattern. */
-    LXW_CHART_PATTERN_LIGHT_UPWARD_DIAGONAL,
-
-    /** Dark downward diagonal pattern. */
-    LXW_CHART_PATTERN_DARK_DOWNWARD_DIAGONAL,
-
-    /** Dark upward diagonal pattern. */
-    LXW_CHART_PATTERN_DARK_UPWARD_DIAGONAL,
-
-    /** Wide downward diagonal pattern. */
-    LXW_CHART_PATTERN_WIDE_DOWNWARD_DIAGONAL,
-
-    /** Wide upward diagonal pattern. */
-    LXW_CHART_PATTERN_WIDE_UPWARD_DIAGONAL,
-
-    /** Light vertical pattern. */
-    LXW_CHART_PATTERN_LIGHT_VERTICAL,
-
-    /** Light horizontal pattern. */
-    LXW_CHART_PATTERN_LIGHT_HORIZONTAL,
-
-    /** Narrow vertical pattern. */
-    LXW_CHART_PATTERN_NARROW_VERTICAL,
-
-    /** Narrow horizontal pattern. */
-    LXW_CHART_PATTERN_NARROW_HORIZONTAL,
-
-    /** Dark vertical pattern. */
-    LXW_CHART_PATTERN_DARK_VERTICAL,
-
-    /** Dark horizontal pattern. */
-    LXW_CHART_PATTERN_DARK_HORIZONTAL,
-
-    /** Dashed downward diagonal pattern. */
-    LXW_CHART_PATTERN_DASHED_DOWNWARD_DIAGONAL,
-
-    /** Dashed upward diagonal pattern. */
-    LXW_CHART_PATTERN_DASHED_UPWARD_DIAGONAL,
-
-    /** Dashed horizontal pattern. */
-    LXW_CHART_PATTERN_DASHED_HORIZONTAL,
-
-    /** Dashed vertical pattern. */
-    LXW_CHART_PATTERN_DASHED_VERTICAL,
-
-    /** Small confetti pattern. */
-    LXW_CHART_PATTERN_SMALL_CONFETTI,
-
-    /** Large confetti pattern. */
-    LXW_CHART_PATTERN_LARGE_CONFETTI,
-
-    /** Zigzag pattern. */
-    LXW_CHART_PATTERN_ZIGZAG,
-
-    /** Wave pattern. */
-    LXW_CHART_PATTERN_WAVE,
-
-    /** Diagonal brick pattern. */
-    LXW_CHART_PATTERN_DIAGONAL_BRICK,
-
-    /** Horizontal brick pattern. */
-    LXW_CHART_PATTERN_HORIZONTAL_BRICK,
-
-    /** Weave pattern. */
-    LXW_CHART_PATTERN_WEAVE,
-
-    /** Plaid pattern. */
-    LXW_CHART_PATTERN_PLAID,
-
-    /** Divot pattern. */
-    LXW_CHART_PATTERN_DIVOT,
-
-    /** Dotted grid pattern. */
-    LXW_CHART_PATTERN_DOTTED_GRID,
-
-    /** Dotted diamond pattern. */
-    LXW_CHART_PATTERN_DOTTED_DIAMOND,
-
-    /** Shingle pattern. */
-    LXW_CHART_PATTERN_SHINGLE,
-
-    /** Trellis pattern. */
-    LXW_CHART_PATTERN_TRELLIS,
-
-    /** Sphere pattern. */
-    LXW_CHART_PATTERN_SPHERE,
-
-    /** Small grid pattern. */
-    LXW_CHART_PATTERN_SMALL_GRID,
-
-    /** Large grid pattern. */
-    LXW_CHART_PATTERN_LARGE_GRID,
-
-    /** Small check pattern. */
-    LXW_CHART_PATTERN_SMALL_CHECK,
-
-    /** Large check pattern. */
-    LXW_CHART_PATTERN_LARGE_CHECK,
-
-    /** Outlined diamond pattern. */
-    LXW_CHART_PATTERN_OUTLINED_DIAMOND,
-
-    /** Solid diamond pattern. */
-    LXW_CHART_PATTERN_SOLID_DIAMOND
-} lxw_chart_pattern_type;
-
-/**
- * @brief Chart data label positions.
- */
-typedef enum lxw_chart_label_position {
-    /** Series data label position: default position. */
-    LXW_CHART_LABEL_POSITION_DEFAULT,
-
-    /** Series data label position: center. */
-    LXW_CHART_LABEL_POSITION_CENTER,
-
-    /** Series data label position: right. */
-    LXW_CHART_LABEL_POSITION_RIGHT,
-
-    /** Series data label position: left. */
-    LXW_CHART_LABEL_POSITION_LEFT,
-
-    /** Series data label position: above. */
-    LXW_CHART_LABEL_POSITION_ABOVE,
-
-    /** Series data label position: below. */
-    LXW_CHART_LABEL_POSITION_BELOW,
-
-    /** Series data label position: inside base.  */
-    LXW_CHART_LABEL_POSITION_INSIDE_BASE,
-
-    /** Series data label position: inside end. */
-    LXW_CHART_LABEL_POSITION_INSIDE_END,
-
-    /** Series data label position: outside end. */
-    LXW_CHART_LABEL_POSITION_OUTSIDE_END,
-
-    /** Series data label position: best fit. */
-    LXW_CHART_LABEL_POSITION_BEST_FIT
-} lxw_chart_label_position;
-
-/**
- * @brief Chart data label separator.
- */
-typedef enum lxw_chart_label_separator {
-    /** Series data label separator: comma (the default). */
-    LXW_CHART_LABEL_SEPARATOR_COMMA,
-
-    /** Series data label separator: semicolon. */
-    LXW_CHART_LABEL_SEPARATOR_SEMICOLON,
-
-    /** Series data label separator: period. */
-    LXW_CHART_LABEL_SEPARATOR_PERIOD,
-
-    /** Series data label separator: newline. */
-    LXW_CHART_LABEL_SEPARATOR_NEWLINE,
-
-    /** Series data label separator: space. */
-    LXW_CHART_LABEL_SEPARATOR_SPACE
-} lxw_chart_label_separator;
-
-/**
- * @brief Chart axis types.
- */
-typedef enum lxw_chart_axis_type {
-    /** Chart X axis. */
-    LXW_CHART_AXIS_TYPE_X,
-
-    /** Chart Y axis. */
-    LXW_CHART_AXIS_TYPE_Y
-} lxw_chart_axis_type;
-
-enum lxw_chart_subtype {
-
-    LXW_CHART_SUBTYPE_NONE = 0,
-    LXW_CHART_SUBTYPE_STACKED,
-    LXW_CHART_SUBTYPE_STACKED_PERCENT
-};
-
-enum lxw_chart_grouping {
-    LXW_GROUPING_CLUSTERED,
-    LXW_GROUPING_STANDARD,
-    LXW_GROUPING_PERCENTSTACKED,
-    LXW_GROUPING_STACKED
-};
-
-/**
- * @brief Axis positions for category axes.
- */
-typedef enum lxw_chart_axis_tick_position {
-
-    LXW_CHART_AXIS_POSITION_DEFAULT,
-
-    /** Position category axis on tick marks. */
-    LXW_CHART_AXIS_POSITION_ON_TICK,
-
-    /** Position category axis between tick marks. */
-    LXW_CHART_AXIS_POSITION_BETWEEN
-} lxw_chart_axis_tick_position;
-
-/**
- * @brief Axis label positions.
- */
-typedef enum lxw_chart_axis_label_position {
-
-    /** Position the axis labels next to the axis. The default. */
-    LXW_CHART_AXIS_LABEL_POSITION_NEXT_TO,
-
-    /** Position the axis labels at the top of the chart, for horizontal
-     * axes, or to the right for vertical axes.*/
-    LXW_CHART_AXIS_LABEL_POSITION_HIGH,
-
-    /** Position the axis labels at the bottom of the chart, for horizontal
-     * axes, or to the left for vertical axes.*/
-    LXW_CHART_AXIS_LABEL_POSITION_LOW,
-
-    /** Turn off the the axis labels. */
-    LXW_CHART_AXIS_LABEL_POSITION_NONE
-} lxw_chart_axis_label_position;
-
-/**
- * @brief Display units for chart value axis.
- */
-typedef enum lxw_chart_axis_display_unit {
-
-    /** Axis display units: None. The default. */
-    LXW_CHART_AXIS_UNITS_NONE,
-
-    /** Axis display units: Hundreds. */
-    LXW_CHART_AXIS_UNITS_HUNDREDS,
-
-    /** Axis display units: Thousands. */
-    LXW_CHART_AXIS_UNITS_THOUSANDS,
-
-    /** Axis display units: Ten thousands. */
-    LXW_CHART_AXIS_UNITS_TEN_THOUSANDS,
-
-    /** Axis display units: Hundred thousands. */
-    LXW_CHART_AXIS_UNITS_HUNDRED_THOUSANDS,
-
-    /** Axis display units: Millions. */
-    LXW_CHART_AXIS_UNITS_MILLIONS,
-
-    /** Axis display units: Ten millions. */
-    LXW_CHART_AXIS_UNITS_TEN_MILLIONS,
-
-    /** Axis display units: Hundred millions. */
-    LXW_CHART_AXIS_UNITS_HUNDRED_MILLIONS,
-
-    /** Axis display units: Billions. */
-    LXW_CHART_AXIS_UNITS_BILLIONS,
-
-    /** Axis display units: Trillions. */
-    LXW_CHART_AXIS_UNITS_TRILLIONS
-} lxw_chart_axis_display_unit;
-
-/**
- * @brief Tick mark types for an axis.
- */
-typedef enum lxw_chart_axis_tick_mark {
-
-    /** Default tick mark for the chart axis. Usually outside. */
-    LXW_CHART_AXIS_TICK_MARK_DEFAULT,
-
-    /** No tick mark for the axis. */
-    LXW_CHART_AXIS_TICK_MARK_NONE,
-
-    /** Tick mark inside the axis only. */
-    LXW_CHART_AXIS_TICK_MARK_INSIDE,
-
-    /** Tick mark outside the axis only. */
-    LXW_CHART_AXIS_TICK_MARK_OUTSIDE,
-
-    /** Tick mark inside and outside the axis. */
-    LXW_CHART_AXIS_TICK_MARK_CROSSING
-} lxw_chart_tick_mark;
-
-typedef struct lxw_series_range {
-    char *formula;
-    char *sheetname;
-    lxw_row_t first_row;
-    lxw_row_t last_row;
-    lxw_col_t first_col;
-    lxw_col_t last_col;
-    uint8_t ignore_cache;
-
-    uint8_t has_string_cache;
-    uint16_t num_data_points;
-    struct lxw_series_data_points *data_cache;
-
-} lxw_series_range;
-
-typedef struct lxw_series_data_point {
-    uint8_t is_string;
-    double number;
-    char *string;
-    uint8_t no_data;
-
-    STAILQ_ENTRY (lxw_series_data_point) list_pointers;
-
-} lxw_series_data_point;
-
-/**
- * @brief Struct to represent a chart line.
- *
- * See @ref chart_lines.
- */
-typedef struct lxw_chart_line {
-
-    /** The chart font color. See @ref working_with_colors. */
-    lxw_color_t color;
-
-    /** Turn off/hide line. Set to 0 or 1.*/
-    uint8_t none;
-
-    /** Width of the line in increments of 0.25. Default is 2.25. */
-    float width;
-
-    /** The line dash type. See #lxw_chart_line_dash_type. */
-    uint8_t dash_type;
-
-    /** Set the transparency of the line. 0 - 100. Default 0. */
-    uint8_t transparency;
-
-    /* Members for internal use only. */
-    uint8_t has_color;
-
-} lxw_chart_line;
-
-/**
- * @brief Struct to represent a chart fill.
- *
- * See @ref chart_fills.
- */
-typedef struct lxw_chart_fill {
-
-    /** The chart font color. See @ref working_with_colors. */
-    lxw_color_t color;
-
-    /** Turn off/hide line. Set to 0 or 1.*/
-    uint8_t none;
-
-    /** Set the transparency of the fill. 0 - 100. Default 0. */
-    uint8_t transparency;
-
-    /* Members for internal use only. */
-    uint8_t has_color;
-
-} lxw_chart_fill;
-
-/**
- * @brief Struct to represent a chart pattern.
- *
- * See @ref chart_patterns.
- */
-typedef struct lxw_chart_pattern {
-
-    /** The pattern foreground color. See @ref working_with_colors. */
-    lxw_color_t fg_color;
-
-    /** The pattern background color. See @ref working_with_colors. */
-    lxw_color_t bg_color;
-
-    /** The pattern type. See #lxw_chart_pattern_type. */
-    uint8_t type;
-
-    /* Members for internal use only. */
-    uint8_t has_fg_color;
-    uint8_t has_bg_color;
-
-} lxw_chart_pattern;
-
-/**
- * @brief Struct to represent a chart font.
- *
- * See @ref chart_fonts.
- */
-typedef struct lxw_chart_font {
-
-    /** The chart font name, such as "Arial" or "Calibri". */
-    char *name;
-
-    /** The chart font size. The default is 11. */
-    double size;
-
-    /** The chart font bold property. Set to 0 or 1. */
-    uint8_t bold;
-
-    /** The chart font italic property. Set to 0 or 1. */
-    uint8_t italic;
-
-    /** The chart font underline property. Set to 0 or 1. */
-    uint8_t underline;
-
-    /** The chart font rotation property. Range: -90 to 90. */
-    int32_t rotation;
-
-    /** The chart font color. See @ref working_with_colors. */
-    lxw_color_t color;
-
-    /** The chart font pitch family property. Rarely required. set to 0. */
-    uint8_t pitch_family;
-
-    /** The chart font character set property. Rarely required. set to 0. */
-    uint8_t charset;
-
-    /** The chart font baseline property. Rarely required. set to 0. */
-    int8_t baseline;
-
-    /* Members for internal use only. */
-
-    uint8_t has_color;
-
-} lxw_chart_font;
-
-typedef struct lxw_chart_marker {
-
-    uint8_t type;
-    uint8_t size;
-    lxw_chart_line *line;
-    lxw_chart_fill *fill;
-    lxw_chart_pattern *pattern;
-
-} lxw_chart_marker;
-
-typedef struct lxw_chart_legend {
-
-    lxw_chart_font *font;
-    uint8_t position;
-
-} lxw_chart_legend;
-
-typedef struct lxw_chart_title {
-
-    char *name;
-    lxw_row_t row;
-    lxw_col_t col;
-    lxw_chart_font *font;
-    uint8_t off;
-    uint8_t is_horizontal;
-    uint8_t ignore_cache;
-
-    /* We use a range to hold the title formula properties even though it
-     * will only have 1 point in order to re-use similar functions.*/
-    lxw_series_range *range;
-
-    struct lxw_series_data_point data_point;
-
-} lxw_chart_title;
-
-/**
- * @brief Struct to represent an Excel chart data point.
- *
- * The lxw_chart_point used to set the line, fill and pattern of one or more
- * points in a chart data series. See @ref chart_points.
- */
-typedef struct lxw_chart_point {
-
-    /** The line/border for the chart point. See @ref chart_lines. */
-    lxw_chart_line *line;
-
-    /** The fill for the chart point. See @ref chart_fills. */
-    lxw_chart_fill *fill;
-
-    /** The pattern for the chart point. See @ref chart_patterns.*/
-    lxw_chart_pattern *pattern;
-
-} lxw_chart_point;
-
-/**
- * @brief Define how blank values are displayed in a chart.
- */
-typedef enum lxw_chart_blank {
-
-    /** Show empty chart cells as gaps in the data. The default. */
-    LXW_CHART_BLANKS_AS_GAP,
-
-    /** Show empty chart cells as zeros. */
-    LXW_CHART_BLANKS_AS_ZERO,
-
-    /** Show empty chart cells as connected. Only for charts with lines. */
-    LXW_CHART_BLANKS_AS_CONNECTED
-} lxw_chart_blank;
-
-enum lxw_chart_position {
-    LXW_CHART_AXIS_RIGHT,
-    LXW_CHART_AXIS_LEFT,
-    LXW_CHART_AXIS_TOP,
-    LXW_CHART_AXIS_BOTTOM
-};
-
-/**
- * @brief Type/amount of data series error bar.
- */
-typedef enum lxw_chart_error_bar_type {
-    /** Error bar type: Standard error. */
-    LXW_CHART_ERROR_BAR_TYPE_STD_ERROR,
-
-    /** Error bar type: Fixed value. */
-    LXW_CHART_ERROR_BAR_TYPE_FIXED,
-
-    /** Error bar type: Percentage. */
-    LXW_CHART_ERROR_BAR_TYPE_PERCENTAGE,
-
-    /** Error bar type: Standard deviation(s). */
-    LXW_CHART_ERROR_BAR_TYPE_STD_DEV
-} lxw_chart_error_bar_type;
-
-/**
- * @brief Direction for a data series error bar.
- */
-typedef enum lxw_chart_error_bar_direction {
-
-    /** Error bar extends in both directions. The default. */
-    LXW_CHART_ERROR_BAR_DIR_BOTH,
-
-    /** Error bar extends in positive direction. */
-    LXW_CHART_ERROR_BAR_DIR_PLUS,
-
-    /** Error bar extends in negative direction. */
-    LXW_CHART_ERROR_BAR_DIR_MINUS
-} lxw_chart_error_bar_direction;
-
-/**
- * @brief Direction for a data series error bar.
- */
-typedef enum lxw_chart_error_bar_axis {
-    /** X axis error bar. */
-    LXW_CHART_ERROR_BAR_AXIS_X,
-
-    /** Y axis error bar. */
-    LXW_CHART_ERROR_BAR_AXIS_Y
-} lxw_chart_error_bar_axis;
-
-/**
- * @brief End cap styles for a data series error bar.
- */
-typedef enum lxw_chart_error_bar_cap {
-    /** Flat end cap. The default. */
-    LXW_CHART_ERROR_BAR_END_CAP,
-
-    /** No end cap. */
-    LXW_CHART_ERROR_BAR_NO_CAP
-} lxw_chart_error_bar_cap;
-
-typedef struct lxw_series_error_bars {
-    uint8_t type;
-    uint8_t direction;
-    uint8_t endcap;
-    uint8_t has_value;
-    uint8_t is_set;
-    uint8_t is_x;
-    uint8_t chart_group;
-    double value;
-    lxw_chart_line *line;
-
-} lxw_series_error_bars;
-
-/**
- * @brief Series trendline/regression types.
- */
-typedef enum lxw_chart_trendline_type {
-    /** Trendline type: Linear. */
-    LXW_CHART_TRENDLINE_TYPE_LINEAR,
-
-    /** Trendline type: Logarithm. */
-    LXW_CHART_TRENDLINE_TYPE_LOG,
-
-    /** Trendline type: Polynomial. */
-    LXW_CHART_TRENDLINE_TYPE_POLY,
-
-    /** Trendline type: Power. */
-    LXW_CHART_TRENDLINE_TYPE_POWER,
-
-    /** Trendline type: Exponential. */
-    LXW_CHART_TRENDLINE_TYPE_EXP,
-
-    /** Trendline type: Moving Average. */
-    LXW_CHART_TRENDLINE_TYPE_AVERAGE
-} lxw_chart_trendline_type;
-
-/**
- * @brief Struct to represent an Excel chart data series.
- *
- * The lxw_chart_series is created using the chart_add_series function. It is
- * used in functions that modify a chart series but the members of the struct
- * aren't modified directly.
- */
-typedef struct lxw_chart_series {
-
-    lxw_series_range *categories;
-    lxw_series_range *values;
-    lxw_chart_title title;
-    lxw_chart_line *line;
-    lxw_chart_fill *fill;
-    lxw_chart_pattern *pattern;
-    lxw_chart_marker *marker;
-    lxw_chart_point *points;
-    uint16_t point_count;
-
-    uint8_t smooth;
-    uint8_t invert_if_negative;
-
-    /* Data label parameters. */
-    uint8_t has_labels;
-    uint8_t show_labels_value;
-    uint8_t show_labels_category;
-    uint8_t show_labels_name;
-    uint8_t show_labels_leader;
-    uint8_t show_labels_legend;
-    uint8_t show_labels_percent;
-    uint8_t label_position;
-    uint8_t label_separator;
-    uint8_t default_label_position;
-    char *label_num_format;
-    lxw_chart_font *label_font;
-
-    lxw_series_error_bars *x_error_bars;
-    lxw_series_error_bars *y_error_bars;
-
-    uint8_t has_trendline;
-    uint8_t has_trendline_forecast;
-    uint8_t has_trendline_equation;
-    uint8_t has_trendline_r_squared;
-    uint8_t has_trendline_intercept;
-    uint8_t trendline_type;
-    uint8_t trendline_value;
-    double trendline_forward;
-    double trendline_backward;
-    uint8_t trendline_value_type;
-    char *trendline_name;
-    lxw_chart_line *trendline_line;
-    double trendline_intercept;
-
-    STAILQ_ENTRY (lxw_chart_series) list_pointers;
-
-} lxw_chart_series;
-
-/* Struct for major/minor axis gridlines. */
-typedef struct lxw_chart_gridline {
-
-    uint8_t visible;
-    lxw_chart_line *line;
-
-} lxw_chart_gridline;
-
-/**
- * @brief Struct to represent an Excel chart axis.
- *
- * The lxw_chart_axis struct is used in functions that modify a chart axis
- * but the members of the struct aren't modified directly.
- */
-typedef struct lxw_chart_axis {
-
-    lxw_chart_title title;
-
-    char *num_format;
-    char *default_num_format;
-    uint8_t source_linked;
-
-    uint8_t major_tick_mark;
-    uint8_t minor_tick_mark;
-    uint8_t is_horizontal;
-
-    lxw_chart_gridline major_gridlines;
-    lxw_chart_gridline minor_gridlines;
-
-    lxw_chart_font *num_font;
-    lxw_chart_line *line;
-    lxw_chart_fill *fill;
-    lxw_chart_pattern *pattern;
-
-    uint8_t is_category;
-    uint8_t is_date;
-    uint8_t is_value;
-    uint8_t axis_position;
-    uint8_t position_axis;
-    uint8_t label_position;
-    uint8_t hidden;
-    uint8_t reverse;
-
-    uint8_t has_min;
-    double min;
-    uint8_t has_max;
-    double max;
-
-    uint8_t has_major_unit;
-    double major_unit;
-    uint8_t has_minor_unit;
-    double minor_unit;
-
-    uint16_t interval_unit;
-    uint16_t interval_tick;
-
-    uint16_t log_base;
-
-    uint8_t display_units;
-    uint8_t display_units_visible;
-
-    uint8_t has_crossing;
-    uint8_t crossing_max;
-    double crossing;
-
-} lxw_chart_axis;
-
-/**
- * @brief Struct to represent an Excel chart.
- *
- * The members of the lxw_chart struct aren't modified directly. Instead
- * the chart properties are set by calling the functions shown in chart.h.
- */
-typedef struct lxw_chart {
-
-    FILE *file;
-
-    uint8_t type;
-    uint8_t subtype;
-    uint16_t series_index;
-
-    void (*write_chart_type) (struct lxw_chart *);
-    void (*write_plot_area) (struct lxw_chart *);
-
-    /**
-     * A pointer to the chart x_axis object which can be used in functions
-     * that configures the X axis.
-     */
-    lxw_chart_axis *x_axis;
-
-    /**
-     * A pointer to the chart y_axis object which can be used in functions
-     * that configures the Y axis.
-     */
-    lxw_chart_axis *y_axis;
-
-    lxw_chart_title title;
-
-    uint32_t id;
-    uint32_t axis_id_1;
-    uint32_t axis_id_2;
-    uint32_t axis_id_3;
-    uint32_t axis_id_4;
-
-    uint8_t in_use;
-    uint8_t chart_group;
-    uint8_t cat_has_num_fmt;
-
-    uint8_t has_horiz_cat_axis;
-    uint8_t has_horiz_val_axis;
-
-    uint8_t style_id;
-    uint16_t rotation;
-    uint16_t hole_size;
-
-    uint8_t no_title;
-    uint8_t has_overlap;
-    int8_t overlap_y1;
-    int8_t overlap_y2;
-    uint16_t gap_y1;
-    uint16_t gap_y2;
-
-    uint8_t grouping;
-    uint8_t default_cross_between;
-
-    lxw_chart_legend legend;
-    int16_t *delete_series;
-    uint16_t delete_series_count;
-    lxw_chart_marker *default_marker;
-
-    lxw_chart_line *chartarea_line;
-    lxw_chart_fill *chartarea_fill;
-    lxw_chart_pattern *chartarea_pattern;
-    lxw_chart_line *plotarea_line;
-    lxw_chart_fill *plotarea_fill;
-    lxw_chart_pattern *plotarea_pattern;
-
-    uint8_t has_drop_lines;
-    lxw_chart_line *drop_lines_line;
-
-    uint8_t has_high_low_lines;
-    lxw_chart_line *high_low_lines_line;
-
-    struct lxw_chart_series_list *series_list;
-
-    uint8_t has_table;
-    uint8_t has_table_vertical;
-    uint8_t has_table_horizontal;
-    uint8_t has_table_outline;
-    uint8_t has_table_legend_keys;
-    lxw_chart_font *table_font;
-
-    uint8_t show_blanks_as;
-    uint8_t show_hidden_data;
-
-    uint8_t has_up_down_bars;
-    lxw_chart_line *up_bar_line;
-    lxw_chart_line *down_bar_line;
-    lxw_chart_fill *up_bar_fill;
-    lxw_chart_fill *down_bar_fill;
-
-    uint8_t default_label_position;
-
-    STAILQ_ENTRY (lxw_chart) ordered_list_pointers;
-    STAILQ_ENTRY (lxw_chart) list_pointers;
-
-} lxw_chart;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_chart *lxw_chart_new(uint8_t type);
-void lxw_chart_free(lxw_chart *chart);
-void lxw_chart_assemble_xml_file(lxw_chart *chart);
-
-/**
- * @brief Add a data series to a chart.
- *
- * @param chart      Pointer to a lxw_chart instance to be configured.
- * @param categories The range of categories in the data series.
- * @param values     The range of values in the data series.
- *
- * @return A lxw_chart_series object pointer.
- *
- * In Excel a chart **series** is a collection of information that defines
- * which data is plotted such as the categories and values. It is also used to
- * define the formatting for the data.
- *
- * For an libxlsxwriter chart object the `%chart_add_series()` function is
- * used to set the categories and values of the series:
- *
- * @code
- *     chart_add_series(chart, "=Sheet1!$A$2:$A$7", "=Sheet1!$C$2:$C$7");
- * @endcode
- *
- *
- * The series parameters are:
- *
- * - `categories`: This sets the chart category labels. The category is more
- *   or less the same as the X axis. In most Excel chart types the
- *   `categories` property is optional and the chart will just assume a
- *   sequential series from `1..n`:
- *
- * @code
- *     // The NULL category will default to 1 to 5 like in Excel.
- *     chart_add_series(chart, NULL, "Sheet1!$A$1:$A$5");
- * @endcode
- *
- *  - `values`: This is the most important property of a series and is the
- *    only mandatory option for every chart object. This parameter links the
- *    chart with the worksheet data that it displays.
- *
- * The `categories` and `values` should be a string formula like
- * `"=Sheet1!$A$2:$A$7"` in the same way it is represented in Excel. This is
- * convenient when recreating a chart from an example in Excel but it is
- * trickier to generate programmatically. For these cases you can set the
- * `categories` and `values` to `NULL` and use the
- * `chart_series_set_categories()` and `chart_series_set_values()` functions:
- *
- * @code
- *     lxw_chart_series *series = chart_add_series(chart, NULL, NULL);
- *
- *     // Configure the series using a syntax that is easier to define programmatically.
- *     chart_series_set_categories(series, "Sheet1", 1, 0, 6, 0); // "=Sheet1!$A$2:$A$7"
- *     chart_series_set_values(    series, "Sheet1", 1, 2, 6, 2); // "=Sheet1!$C$2:$C$7"
- * @endcode
- *
- * As shown in the previous example the return value from
- * `%chart_add_series()` is a lxw_chart_series pointer. This can be used in
- * other functions that configure a series.
- *
- *
- * More than one series can be added to a chart. The series numbering and
- * order in the Excel chart will be the same as the order in which they are
- * added in libxlsxwriter:
- *
- * @code
- *    chart_add_series(chart, NULL, "Sheet1!$A$1:$A$5");
- *    chart_add_series(chart, NULL, "Sheet1!$B$1:$B$5");
- *    chart_add_series(chart, NULL, "Sheet1!$C$1:$C$5");
- * @endcode
- *
- * It is also possible to specify non-contiguous ranges:
- *
- * @code
- *    chart_add_series(
- *        chart,
- *        "=(Sheet1!$A$1:$A$9,Sheet1!$A$14:$A$25)",
- *        "=(Sheet1!$B$1:$B$9,Sheet1!$B$14:$B$25)"
- *    );
- * @endcode
- *
- */
-lxw_chart_series *chart_add_series(lxw_chart *chart,
-                                   const char *categories,
-                                   const char *values);
-
-/**
- * @brief Set a series "categories" range using row and column values.
- *
- * @param series    A series object created via `chart_add_series()`.
- * @param sheetname The name of the worksheet that contains the data range.
- * @param first_row The first row of the range. (All zero indexed.)
- * @param first_col The first column of the range.
- * @param last_row  The last row of the range.
- * @param last_col  The last col of the range.
- *
- * The `categories` and `values` of a chart data series are generally set
- * using the `chart_add_series()` function and Excel range formulas like
- * `"=Sheet1!$A$2:$A$7"`.
- *
- * The `%chart_series_set_categories()` function is an alternative method that
- * is easier to generate programmatically. It requires that you set the
- * `categories` and `values` parameters in `chart_add_series()`to `NULL` and
- * then set them using row and column values in
- * `chart_series_set_categories()` and `chart_series_set_values()`:
- *
- * @code
- *     lxw_chart_series *series = chart_add_series(chart, NULL, NULL);
- *
- *     // Configure the series ranges programmatically.
- *     chart_series_set_categories(series, "Sheet1", 1, 0, 6, 0); // "=Sheet1!$A$2:$A$7"
- *     chart_series_set_values(    series, "Sheet1", 1, 2, 6, 2); // "=Sheet1!$C$2:$C$7"
- * @endcode
- *
- */
-void chart_series_set_categories(lxw_chart_series *series,
-                                 const char *sheetname, lxw_row_t first_row,
-                                 lxw_col_t first_col, lxw_row_t last_row,
-                                 lxw_col_t last_col);
-
-/**
- * @brief Set a series "values" range using row and column values.
- *
- * @param series    A series object created via `chart_add_series()`.
- * @param sheetname The name of the worksheet that contains the data range.
- * @param first_row The first row of the range. (All zero indexed.)
- * @param first_col The first column of the range.
- * @param last_row  The last row of the range.
- * @param last_col  The last col of the range.
- *
- * The `categories` and `values` of a chart data series are generally set
- * using the `chart_add_series()` function and Excel range formulas like
- * `"=Sheet1!$A$2:$A$7"`.
- *
- * The `%chart_series_set_values()` function is an alternative method that is
- * easier to generate programmatically. See the documentation for
- * `chart_series_set_categories()` above.
- */
-void chart_series_set_values(lxw_chart_series *series, const char *sheetname,
-                             lxw_row_t first_row, lxw_col_t first_col,
-                             lxw_row_t last_row, lxw_col_t last_col);
-
-/**
- * @brief Set the name of a chart series range.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param name   The series name.
- *
- * The `%chart_series_set_name` function is used to set the name for a chart
- * data series. The series name in Excel is displayed in the chart legend and
- * in the formula bar. The name property is optional and if it isn't supplied
- * it will default to `Series 1..n`.
- *
- * The function applies to a #lxw_chart_series object created using
- * `chart_add_series()`:
- *
- * @code
- *     lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$B$2:$B$7");
- *
- *     chart_series_set_name(series, "Quarterly budget data");
- * @endcode
- *
- * The name parameter can also be a formula such as `=Sheet1!$A$1` to point to
- * a cell in the workbook that contains the name:
- *
- * @code
- *     lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$B$2:$B$7");
- *
- *     chart_series_set_name(series, "=Sheet1!$B1$1");
- * @endcode
- *
- * See also the `chart_series_set_name_range()` function to see how to set the
- * name formula programmatically.
- */
-void chart_series_set_name(lxw_chart_series *series, const char *name);
-
-/**
- * @brief Set a series name formula using row and column values.
- *
- * @param series    A series object created via `chart_add_series()`.
- * @param sheetname The name of the worksheet that contains the cell range.
- * @param row       The zero indexed row number of the range.
- * @param col       The zero indexed column number of the range.
- *
- * The `%chart_series_set_name_range()` function can be used to set a series
- * name range and is an alternative to using `chart_series_set_name()` and a
- * string formula:
- *
- * @code
- *     lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$B$2:$B$7");
- *
- *     chart_series_set_name_range(series, "Sheet1", 0, 2); // "=Sheet1!$C$1"
- * @endcode
- */
-void chart_series_set_name_range(lxw_chart_series *series,
-                                 const char *sheetname, lxw_row_t row,
-                                 lxw_col_t col);
-/**
- * @brief Set the line properties for a chart series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param line   A #lxw_chart_line struct.
- *
- * Set the line/border properties of a chart series:
- *
- * @code
- *     lxw_chart_line line = {.color = LXW_COLOR_RED};
- *
- *     chart_series_set_line(series1, &line);
- *     chart_series_set_line(series2, &line);
- *     chart_series_set_line(series3, &line);
- * @endcode
- *
- * @image html chart_series_set_line.png
- *
- * For more information see @ref chart_lines.
- */
-void chart_series_set_line(lxw_chart_series *series, lxw_chart_line *line);
-
-/**
- * @brief Set the fill properties for a chart series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param fill   A #lxw_chart_fill struct.
- *
- * Set the fill properties of a chart series:
- *
- * @code
- *     lxw_chart_fill fill1 = {.color = LXW_COLOR_RED};
- *     lxw_chart_fill fill2 = {.color = LXW_COLOR_YELLOW};
- *     lxw_chart_fill fill3 = {.color = LXW_COLOR_GREEN};
- *
- *     chart_series_set_fill(series1, &fill1);
- *     chart_series_set_fill(series2, &fill2);
- *     chart_series_set_fill(series3, &fill3);
- * @endcode
- *
- * @image html chart_series_set_fill.png
- *
- * For more information see @ref chart_fills.
- */
-void chart_series_set_fill(lxw_chart_series *series, lxw_chart_fill *fill);
-
-/**
- * @brief Invert the fill color for negative series values.
- *
- * @param series  A series object created via `chart_add_series()`.
- *
- * Invert the fill color for negative values. Usually only applicable to
- * column and bar charts.
- *
- * @code
- *     chart_series_set_invert_if_negative(series);
- * @endcode
- *
- */
-void chart_series_set_invert_if_negative(lxw_chart_series *series);
-
-/**
- * @brief Set the pattern properties for a chart series.
- *
- * @param series  A series object created via `chart_add_series()`.
- * @param pattern A #lxw_chart_pattern struct.
- *
- * Set the pattern properties of a chart series:
- *
- * @code
- *     lxw_chart_pattern pattern1 = {.type = LXW_CHART_PATTERN_SHINGLE,
- *                                   .fg_color = 0x804000,
- *                                   .bg_color = 0XC68C53};
- *
- *     lxw_chart_pattern pattern2 = {.type = LXW_CHART_PATTERN_HORIZONTAL_BRICK,
- *                                   .fg_color = 0XB30000,
- *                                   .bg_color = 0XFF6666};
- *
- *     chart_series_set_pattern(series1, &pattern1);
- *     chart_series_set_pattern(series2, &pattern2);
- *
- * @endcode
- *
- * @image html chart_pattern.png
- *
- * For more information see #lxw_chart_pattern_type and @ref chart_patterns.
- */
-void chart_series_set_pattern(lxw_chart_series *series,
-                              lxw_chart_pattern *pattern);
-
-/**
- * @brief Set the data marker type for a series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param type   The marker type, see #lxw_chart_marker_type.
- *
- * In Excel a chart marker is used to distinguish data points in a plotted
- * series. In general only Line and Scatter and Radar chart types use
- * markers. The libxlsxwriter chart types that can have markers are:
- *
- * - #LXW_CHART_LINE
- * - #LXW_CHART_SCATTER
- * - #LXW_CHART_SCATTER_STRAIGHT
- * - #LXW_CHART_SCATTER_STRAIGHT_WITH_MARKERS
- * - #LXW_CHART_SCATTER_SMOOTH
- * - #LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS
- * - #LXW_CHART_RADAR
- * - #LXW_CHART_RADAR_WITH_MARKERS
- *
- * The chart types with `MARKERS` in the name have markers with default colors
- * and shapes turned on by default but it is possible using the various
- * `chart_series_set_marker_xxx()` functions below to change these defaults. It
- * is also possible to turn on an off markers.
- *
- * The `%chart_series_set_marker_type()` function is used to specify the
- * type of the series marker:
- *
- * @code
- *     chart_series_set_marker_type(series, LXW_CHART_MARKER_DIAMOND);
- * @endcode
- *
- * @image html chart_marker1.png
- *
- * The available marker types defined by #lxw_chart_marker_type are:
- *
- * - #LXW_CHART_MARKER_AUTOMATIC
- * - #LXW_CHART_MARKER_NONE
- * - #LXW_CHART_MARKER_SQUARE
- * - #LXW_CHART_MARKER_DIAMOND
- * - #LXW_CHART_MARKER_TRIANGLE
- * - #LXW_CHART_MARKER_X
- * - #LXW_CHART_MARKER_STAR
- * - #LXW_CHART_MARKER_SHORT_DASH
- * - #LXW_CHART_MARKER_LONG_DASH
- * - #LXW_CHART_MARKER_CIRCLE
- * - #LXW_CHART_MARKER_PLUS
- *
- * The `#LXW_CHART_MARKER_NONE` type can be used to turn off default markers:
- *
- * @code
- *     chart_series_set_marker_type(series, LXW_CHART_MARKER_NONE);
- * @endcode
- *
- * @image html chart_series_set_marker_none.png
- *
- * The `#LXW_CHART_MARKER_AUTOMATIC` type is a special case which turns on a
- * marker using the default marker style for the particular series. If
- * automatic is on then other marker properties such as size, line or fill
- * cannot be set.
- */
-void chart_series_set_marker_type(lxw_chart_series *series, uint8_t type);
-
-/**
- * @brief Set the size of a data marker for a series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param size   The size of the marker.
- *
- * The `%chart_series_set_marker_size()` function is used to specify the
- * size of the series marker:
- *
- * @code
- *     chart_series_set_marker_type(series, LXW_CHART_MARKER_CIRCLE);
- *     chart_series_set_marker_size(series, 10);
- * @endcode
- *
- * @image html chart_series_set_marker_size.png
- *
- */
-void chart_series_set_marker_size(lxw_chart_series *series, uint8_t size);
-
-/**
- * @brief Set the line properties for a chart series marker.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param line   A #lxw_chart_line struct.
- *
- * Set the line/border properties of a chart marker:
- *
- * @code
- *     lxw_chart_line line = {.color = LXW_COLOR_BLACK};
- *     lxw_chart_fill fill = {.color = LXW_COLOR_RED};
- *
- *     chart_series_set_marker_type(series, LXW_CHART_MARKER_SQUARE);
- *     chart_series_set_marker_size(series, 8);
- *
- *     chart_series_set_marker_line(series, &line);
- *     chart_series_set_marker_fill(series, &fill);
- * @endcode
- *
- * @image html chart_marker2.png
- *
- * For more information see @ref chart_lines.
- */
-void chart_series_set_marker_line(lxw_chart_series *series,
-                                  lxw_chart_line *line);
-
-/**
- * @brief Set the fill properties for a chart series marker.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param fill   A #lxw_chart_fill struct.
- *
- * Set the fill properties of a chart marker:
- *
- * @code
- *     chart_series_set_marker_fill(series, &fill);
- * @endcode
- *
- * See the example and image above and also see @ref chart_fills.
- */
-void chart_series_set_marker_fill(lxw_chart_series *series,
-                                  lxw_chart_fill *fill);
-
-/**
- * @brief Set the pattern properties for a chart series marker.
- *
- * @param series  A series object created via `chart_add_series()`.
- * @param pattern A #lxw_chart_pattern struct.
- *
- * Set the pattern properties of a chart marker:
- *
- * @code
- *     chart_series_set_marker_pattern(series, &pattern);
- * @endcode
- *
- * For more information see #lxw_chart_pattern_type and @ref chart_patterns.
- */
-void chart_series_set_marker_pattern(lxw_chart_series *series,
-                                     lxw_chart_pattern *pattern);
-
-/**
- * @brief Set the formatting for points in the series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param points An NULL terminated array of #lxw_chart_point pointers.
- *
- * @return A #lxw_error.
- *
- * In general formatting is applied to an entire series in a chart. However,
- * it is occasionally required to format individual points in a series. In
- * particular this is required for Pie/Doughnut charts where each segment is
- * represented by a point.
- *
- * @dontinclude chart_pie_colors.c
- * @skip Add the data series
- * @until chart_series_set_points
- *
- * @image html chart_points1.png
- *
- * @note The array of #lxw_chart_point pointers should be NULL terminated
- * as shown in the example.
- *
- * For more details see @ref chart_points
- */
-lxw_error chart_series_set_points(lxw_chart_series *series,
-                                  lxw_chart_point *points[]);
-
-/**
- * @brief Smooth a line or scatter chart series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param smooth Turn off/on the line smoothing. (0/1)
- *
- * The `chart_series_set_smooth()` function is used to set the smooth property
- * of a line series. It is only applicable to the line and scatter chart
- * types:
- *
- * @code
- *     chart_series_set_smooth(series2, LXW_TRUE);
- * @endcode
- *
- * @image html chart_smooth.png
- *
- *
- */
-void chart_series_set_smooth(lxw_chart_series *series, uint8_t smooth);
-
-/**
- * @brief Add data labels to a chart series.
- *
- * @param series A series object created via `chart_add_series()`.
- *
- * The `%chart_series_set_labels()` function is used to turn on data labels
- * for a chart series. Data labels indicate the values of the plotted data
- * points.
- *
- * @code
- *     chart_series_set_labels(series);
- * @endcode
- *
- * @image html chart_labels1.png
- *
- * By default data labels are displayed in Excel with only the values shown:
- *
- * @image html chart_labels2.png
- *
- * However, it is possible to configure other display options, as shown
- * in the functions below.
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels(lxw_chart_series *series);
-
-/**
- * @brief Set the display options for the labels of a data series.
- *
- * @param series        A series object created via `chart_add_series()`.
- * @param show_name     Turn on/off the series name in the label caption.
- * @param show_category Turn on/off the category name in the label caption.
- * @param show_value    Turn on/off the value in the label caption.
- *
- * The `%chart_series_set_labels_options()` function is used to set the
- * parameters that are displayed in the series data label:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_options(series, LXW_TRUE, LXW_TRUE, LXW_TRUE);
- * @endcode
- *
- * @image html chart_labels3.png
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_options(lxw_chart_series *series,
-                                     uint8_t show_name, uint8_t show_category,
-                                     uint8_t show_value);
-
-/**
- * @brief Set the separator for the data label captions.
- *
- * @param series    A series object created via `chart_add_series()`.
- * @param separator The separator for the data label options:
- *                  #lxw_chart_label_separator.
- *
- * The `%chart_series_set_labels_separator()` function is used to change the
- * separator between multiple data label items. The default options is a comma
- * separator as shown in the previous example.
- *
- * The available options are:
- *
- * - #LXW_CHART_LABEL_SEPARATOR_SEMICOLON: semicolon separator.
- * - #LXW_CHART_LABEL_SEPARATOR_PERIOD: a period (dot) separator.
- * - #LXW_CHART_LABEL_SEPARATOR_NEWLINE: a newline separator.
- * - #LXW_CHART_LABEL_SEPARATOR_SPACE: a space separator.
- *
- * For example:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_options(series, LXW_TRUE, LXW_TRUE, LXW_TRUE);
- *     chart_series_set_labels_separator(series, LXW_CHART_LABEL_SEPARATOR_NEWLINE);
- * @endcode
- *
- * @image html chart_labels4.png
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_separator(lxw_chart_series *series,
-                                       uint8_t separator);
-
-/**
- * @brief Set the data label position for a series.
- *
- * @param series   A series object created via `chart_add_series()`.
- * @param position The data label position: #lxw_chart_label_position.
- *
- * The `%chart_series_set_labels_position()` function sets the position of
- * the labels in the data series:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_position(series, LXW_CHART_LABEL_POSITION_ABOVE);
- * @endcode
- *
- * @image html chart_labels5.png
- *
- * In Excel the allowable data label positions vary for different chart
- * types. The allowable, and default, positions are:
- *
- * | Position                              | Line, Scatter | Bar, Column   | Pie, Doughnut | Area, Radar   |
- * | :------------------------------------ | :------------ | :------------ | :------------ | :------------ |
- * | #LXW_CHART_LABEL_POSITION_CENTER      | Yes           | Yes           | Yes           | Yes (default) |
- * | #LXW_CHART_LABEL_POSITION_RIGHT       | Yes (default) |               |               |               |
- * | #LXW_CHART_LABEL_POSITION_LEFT        | Yes           |               |               |               |
- * | #LXW_CHART_LABEL_POSITION_ABOVE       | Yes           |               |               |               |
- * | #LXW_CHART_LABEL_POSITION_BELOW       | Yes           |               |               |               |
- * | #LXW_CHART_LABEL_POSITION_INSIDE_BASE |               | Yes           |               |               |
- * | #LXW_CHART_LABEL_POSITION_INSIDE_END  |               | Yes           | Yes           |               |
- * | #LXW_CHART_LABEL_POSITION_OUTSIDE_END |               | Yes (default) | Yes           |               |
- * | #LXW_CHART_LABEL_POSITION_BEST_FIT    |               |               | Yes (default) |               |
- *
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_position(lxw_chart_series *series,
-                                      uint8_t position);
-
-/**
- * @brief Set leader lines for Pie and Doughnut charts.
- *
- * @param series A series object created via `chart_add_series()`.
- *
- * The `%chart_series_set_labels_leader_line()` function  is used to turn on
- * leader lines for the data label of a series. It is mainly used for pie
- * or doughnut charts:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_leader_line(series);
- * @endcode
- *
- * @note Even when leader lines are turned on they aren't automatically
- *       visible in Excel or XlsxWriter. Due to an Excel limitation
- *       (or design) leader lines only appear if the data label is moved
- *       manually or if the data labels are very close and need to be
- *       adjusted automatically.
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_leader_line(lxw_chart_series *series);
-
-/**
- * @brief Set the legend key for a data label in a chart series.
- *
- * @param series A series object created via `chart_add_series()`.
- *
- * The `%chart_series_set_labels_legend()` function is used to set the
- * legend key for a data series:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_legend(series);
- * @endcode
- *
- * @image html chart_labels6.png
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_legend(lxw_chart_series *series);
-
-/**
- * @brief Set the percentage for a Pie/Doughnut data point.
- *
- * @param series A series object created via `chart_add_series()`.
- *
- * The `%chart_series_set_labels_percentage()` function is used to turn on
- * the display of data labels as a percentage for a series. It is mainly
- * used for pie charts:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_options(series, LXW_FALSE, LXW_FALSE, LXW_FALSE);
- *     chart_series_set_labels_percentage(series);
- * @endcode
- *
- * @image html chart_labels7.png
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_percentage(lxw_chart_series *series);
-
-/**
- * @brief Set the number format for chart data labels in a series.
- *
- * @param series     A series object created via `chart_add_series()`.
- * @param num_format The number format string.
- *
- * The `%chart_series_set_labels_num_format()` function is used to set the
- * number format for data labels:
- *
- * @code
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_num_format(series, "$0.00");
- * @endcode
- *
- * @image html chart_labels8.png
- *
- * The number format is similar to the Worksheet Cell Format num_format,
- * see `format_set_num_format()`.
- *
- * For more information see @ref chart_labels.
- */
-void chart_series_set_labels_num_format(lxw_chart_series *series,
-                                        const char *num_format);
-
-/**
- * @brief Set the font properties for chart data labels in a series
- *
- * @param series A series object created via `chart_add_series()`.
- * @param font   A pointer to a chart #lxw_chart_font font struct.
- *
- *
- * The `%chart_series_set_labels_font()` function is used to set the font
- * for data labels:
- *
- * @code
- *     lxw_chart_font font = {.name = "Consolas", .color = LXW_COLOR_RED};
- *
- *     chart_series_set_labels(series);
- *     chart_series_set_labels_font(series, &font);
- * @endcode
- *
- * @image html chart_labels9.png
- *
- * For more information see @ref chart_fonts and @ref chart_labels.
- *
- */
-void chart_series_set_labels_font(lxw_chart_series *series,
-                                  lxw_chart_font *font);
-
-/**
- * @brief Turn on a trendline for a chart data series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param type   The type of trendline: #lxw_chart_trendline_type.
- * @param value  The order/period value for polynomial and moving average
- *               trendlines.
- *
- * A trendline can be added to a chart series to indicate trends in the data
- * such as a moving average or a polynomial fit. The trendlines types are
- * shown in the following Excel dialog:
- *
- * @image html chart_trendline0.png
- *
- * The `%chart_series_set_trendline()` function turns on these trendlines for
- * a data series:
- *
- * @code
- *     chart = workbook_add_chart(workbook, LXW_CHART_LINE);
- *     series = chart_add_series(chart, NULL, "Sheet1!$A$1:$A$6");
- *
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- * @endcode
- *
- * @image html chart_trendline2.png
- *
- * The `value` parameter corresponds to *order* for a polynomial trendline
- * and *period* for a Moving Average trendline. It both cases it must be >= 2.
- * The `value` parameter  is ignored for all other trendlines:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_AVERAGE, 2);
- * @endcode
- *
- * @image html chart_trendline3.png
- *
- * The allowable values for the the trendline `type` are:
- *
- * - #LXW_CHART_TRENDLINE_TYPE_LINEAR: Linear trendline.
- * - #LXW_CHART_TRENDLINE_TYPE_LOG: Logarithm trendline.
- * - #LXW_CHART_TRENDLINE_TYPE_POLY: Polynomial trendline. The `value`
- *   parameter corresponds to *order*.
- * - #LXW_CHART_TRENDLINE_TYPE_POWER: Power trendline.
- * - #LXW_CHART_TRENDLINE_TYPE_EXP: Exponential trendline.
- * - #LXW_CHART_TRENDLINE_TYPE_AVERAGE: Moving Average trendline. The `value`
- *   parameter corresponds to *period*.
- *
- * Other trendline options, such as those shown in the following Excel
- * dialog, can be set using the functions below.
- *
- * @image html chart_trendline1.png
- *
- * For more information see @ref chart_trendlines.
- */
-void chart_series_set_trendline(lxw_chart_series *series, uint8_t type,
-                                uint8_t value);
-
-/**
- * @brief Set the trendline forecast for a chart data series.
- *
- * @param series   A series object created via `chart_add_series()`.
- * @param forward  The forward period.
- * @param backward The backwards period.
- *
- * The `%chart_series_set_trendline_forecast()` function sets the forward
- * and backward forecast periods for the trendline:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *     chart_series_set_trendline_forecast(series, 0.5, 0.5);
- * @endcode
- *
- * @image html chart_trendline4.png
- *
- * @note This feature isn't available for Moving Average in Excel.
- *
- * For more information see @ref chart_trendlines.
- */
-void chart_series_set_trendline_forecast(lxw_chart_series *series,
-                                         double forward, double backward);
-
-/**
- * @brief Display the equation of a trendline for a chart data series.
- *
- * @param series A series object created via `chart_add_series()`.
- *
- * The `%chart_series_set_trendline_equation()` function displays the
- * equation of the trendline on the chart:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *     chart_series_set_trendline_equation(series);
- * @endcode
- *
- * @image html chart_trendline5.png
- *
- * @note This feature isn't available for Moving Average in Excel.
- *
- * For more information see @ref chart_trendlines.
- */
-void chart_series_set_trendline_equation(lxw_chart_series *series);
-
-/**
- * @brief Display the R squared value of a trendline for a chart data series.
- *
- * @param series A series object created via `chart_add_series()`.
- *
- * The `%chart_series_set_trendline_r_squared()` function displays the
- * R-squared value for the trendline on the chart:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *     chart_series_set_trendline_r_squared(series);
- * @endcode
- *
- * @image html chart_trendline6.png
- *
- * @note This feature isn't available for Moving Average in Excel.
- *
- * For more information see @ref chart_trendlines.
- */
-void chart_series_set_trendline_r_squared(lxw_chart_series *series);
-
-/**
- * @brief Set the trendline Y-axis intercept for a chart data series.
- *
- * @param series    A series object created via `chart_add_series()`.
- * @param intercept Y-axis intercept value.
- *
- * The `%chart_series_set_trendline_intercept()` function sets the Y-axis
- * intercept for the trendline:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *     chart_series_set_trendline_equation(series);
- *     chart_series_set_trendline_intercept(series, 0.8);
- * @endcode
- *
- * @image html chart_trendline7.png
- *
- * As can be seen from the equation on the chart the intercept point
- * (when X=0) is the same as the value set in the equation.
- *
- * @note The intercept feature is only available in Excel for Exponential,
- *       Linear and Polynomial trendline types.
- *
- * For more information see @ref chart_trendlines.
- */
-void chart_series_set_trendline_intercept(lxw_chart_series *series,
-                                          double intercept);
-
-/**
- * @brief Set the trendline name for a chart data series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param name   The name of the trendline to display in the legend.
- *
- * The `%chart_series_set_trendline_name()` function sets the name of the
- * trendline that is displayed in the chart legend. In the examples above
- * the trendlines are displayed with default names like "Linear (Series 1)"
- * and "2 per Mov. Avg. (Series 1)". If these names are too verbose or not
- * descriptive enough you can set your own trendline name:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *     chart_series_set_trendline_name(series, "My trendline");
- * @endcode
- *
- * @image html chart_trendline8.png
- *
- * It is often preferable to turn off the trendline caption in the legend.
- * This is down in Excel by deleting the trendline name from the legend.
- * In libxlsxwriter this is done using the `chart_legend_delete_series()`
- * function to delete the zero based series numbers:
- *
- * @code
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *
- *     // Delete the series name for the second series (=1 in zero base).
- *     // The -1 value indicates the end of the array of values.
- *     int16_t names[] = {1, -1};
- *     chart_legend_delete_series(chart, names);
- * @endcode
- *
- * @image html chart_trendline9.png
- *
- * For more information see @ref chart_trendlines.
- */
-void chart_series_set_trendline_name(lxw_chart_series *series,
-                                     const char *name);
-
-/**
- * @brief Set the trendline line properties for a chart data series.
- *
- * @param series A series object created via `chart_add_series()`.
- * @param line   A #lxw_chart_line struct.
- *
- * The `%chart_series_set_trendline_line()` function is used to set the line
- * properties of a trendline:
- *
- * @code
- *     lxw_chart_line line = {.color     = LXW_COLOR_RED,
- *                            .dash_type = LXW_CHART_LINE_DASH_LONG_DASH};
- *
- *     chart_series_set_trendline(series, LXW_CHART_TRENDLINE_TYPE_LINEAR, 0);
- *     chart_series_set_trendline_line(series, &line);
- * @endcode
- *
- * @image html chart_trendline10.png
- *
- * For more information see @ref chart_trendlines and @ref chart_lines.
- */
-void chart_series_set_trendline_line(lxw_chart_series *series,
-                                     lxw_chart_line *line);
-/**
- * @brief           Get a pointer to X or Y error bars from a chart series.
- *
- * @param series    A series object created via `chart_add_series()`.
- * @param axis_type The axis type (X or Y): #lxw_chart_error_bar_axis.
- *
- * The `%chart_series_get_error_bars()` function returns a pointer to the
- * error bars of a series based on the type of #lxw_chart_error_bar_axis:
- *
- * @code
- *     lxw_series_error_bars *x_error_bars;
- *     lxw_series_error_bars *y_error_bars;
- *
- *     x_error_bars = chart_series_get_error_bars(series, LXW_CHART_ERROR_BAR_AXIS_X);
- *     y_error_bars = chart_series_get_error_bars(series, LXW_CHART_ERROR_BAR_AXIS_Y);
- *
- *     // Use the error bar pointers.
- *     chart_series_set_error_bars(x_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_DEV, 1);
- *
- *     chart_series_set_error_bars(y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_ERROR, 0);
- * @endcode
- *
- * Note, the series error bars can also be accessed directly:
- *
- * @code
- *     // Equivalent to the above example, without function calls.
- *     chart_series_set_error_bars(series->x_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_DEV, 1);
- *
- *     chart_series_set_error_bars(series->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_ERROR, 0);
- * @endcode
- *
- * @return Pointer to the series error bars, or NULL if not found.
- */
-
-lxw_series_error_bars *chart_series_get_error_bars(lxw_chart_series *series, lxw_chart_error_bar_axis
-                                                   axis_type);
-
-/**
- * Set the X or Y error bars for a chart series.
- *
- * @param error_bars A pointer to the series X or Y error bars.
- * @param type       The type of error bar: #lxw_chart_error_bar_type.
- * @param value      The error value.
- *
- * Error bars can be added to a chart series to indicate error bounds in the
- * data. The error bars can be vertical `y_error_bars` (the most common type)
- * or horizontal `x_error_bars` (for Bar and Scatter charts only).
- *
- * @image html chart_error_bars0.png
- *
- * The `%chart_series_set_error_bars()` function sets the error bar type
- * and value associated with the type:
- *
- * @code
- *     lxw_chart_series *series = chart_add_series(chart,
- *                                                 "=Sheet1!$A$1:$A$5",
- *                                                 "=Sheet1!$B$1:$B$5");
- *
- *     chart_series_set_error_bars(series->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_ERROR, 0);
- * @endcode
- *
- * @image html chart_error_bars1.png
- *
- * The error bar types that be used are:
- *
- * - #LXW_CHART_ERROR_BAR_TYPE_STD_ERROR: Standard error.
- * - #LXW_CHART_ERROR_BAR_TYPE_FIXED: Fixed value.
- * - #LXW_CHART_ERROR_BAR_TYPE_PERCENTAGE: Percentage.
- * - #LXW_CHART_ERROR_BAR_TYPE_STD_DEV: Standard deviation(s).
- *
- * @note Custom error bars are not currently supported.
- *
- * All error bar types, apart from Standard error, should have a valid
- * value to set the error range:
- *
- * @code
- *     chart_series_set_error_bars(series1->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_FIXED, 2);
- *
- *     chart_series_set_error_bars(series2->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_PERCENTAGE, 5);
- *
- *     chart_series_set_error_bars(series3->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_DEV, 1);
- * @endcode
- *
- * For the Standard error type the value is ignored.
- *
- * For more information see @ref chart_error_bars.
- */
-void chart_series_set_error_bars(lxw_series_error_bars *error_bars,
-                                 uint8_t type, double value);
-
-/**
- * @brief Set the direction (up, down or both) of the error bars for a chart
- *        series.
- *
- * @param error_bars A pointer to the series X or Y error bars.
- * @param direction  The bar direction: #lxw_chart_error_bar_direction.
- *
- * The `%chart_series_set_error_bars_direction()` function sets the
- * direction of the error bars:
- *
- * @code
- *     chart_series_set_error_bars(series->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_ERROR, 0);
- *
- *     chart_series_set_error_bars_direction(series->y_error_bars,
- *                                           LXW_CHART_ERROR_BAR_DIR_PLUS);
- * @endcode
- *
- * @image html chart_error_bars2.png
- *
- * The valid directions are:
- *
- * - #LXW_CHART_ERROR_BAR_DIR_BOTH: Error bar extends in both directions.
- *   The default.
- * - #LXW_CHART_ERROR_BAR_DIR_PLUS: Error bar extends in positive direction.
- * - #LXW_CHART_ERROR_BAR_DIR_MINUS: Error bar extends in negative direction.
- *
- * For more information see @ref chart_error_bars.
- */
-void chart_series_set_error_bars_direction(lxw_series_error_bars *error_bars,
-                                           uint8_t direction);
-
-/**
- * @brief Set the end cap type for the error bars of a chart series.
- *
- * @param error_bars A pointer to the series X or Y error bars.
- * @param endcap     The error bar end cap type: #lxw_chart_error_bar_cap .
- *
- * The `%chart_series_set_error_bars_endcap()` function sets the end cap
- * type for the error bars:
- *
- * @code
- *     chart_series_set_error_bars(series->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_ERROR, 0);
- *
- *     chart_series_set_error_bars_endcap(series->y_error_bars,
-                                          LXW_CHART_ERROR_BAR_NO_CAP);
- * @endcode
- *
- * @image html chart_error_bars3.png
- *
- * The valid values are:
- *
- * - #LXW_CHART_ERROR_BAR_END_CAP: Flat end cap. The default.
- * - #LXW_CHART_ERROR_BAR_NO_CAP: No end cap.
- *
- * For more information see @ref chart_error_bars.
- */
-void chart_series_set_error_bars_endcap(lxw_series_error_bars *error_bars,
-                                        uint8_t endcap);
-
-/**
- * @brief Set the line properties for a chart series error bars.
- *
- * @param error_bars A pointer to the series X or Y error bars.
- * @param line       A #lxw_chart_line struct.
- *
- * The `%chart_series_set_error_bars_line()` function sets the line
- * properties for the error bars:
- *
- * @code
- *     lxw_chart_line line = {.color     = LXW_COLOR_RED,
- *                            .dash_type = LXW_CHART_LINE_DASH_ROUND_DOT};
- *
- *     chart_series_set_error_bars(series->y_error_bars,
- *                                 LXW_CHART_ERROR_BAR_TYPE_STD_ERROR, 0);
- *
- *     chart_series_set_error_bars_line(series->y_error_bars, &line);
- * @endcode
- *
- * @image html chart_error_bars4.png
- *
- * For more information see @ref chart_lines and @ref chart_error_bars.
- */
-void chart_series_set_error_bars_line(lxw_series_error_bars *error_bars,
-                                      lxw_chart_line *line);
-
-/**
- * @brief           Get an axis pointer from a chart.
- *
- * @param chart     Pointer to a lxw_chart instance to be configured.
- * @param axis_type The axis type (X or Y): #lxw_chart_axis_type.
- *
- * The `%chart_axis_get()` function returns a pointer to a chart axis based
- * on the  #lxw_chart_axis_type:
- *
- * @code
- *     lxw_chart_axis *x_axis = chart_axis_get(chart, LXW_CHART_AXIS_TYPE_X);
- *     lxw_chart_axis *y_axis = chart_axis_get(chart, LXW_CHART_AXIS_TYPE_Y);
- *
- *     // Use the axis pointer in other functions.
- *     chart_axis_major_gridlines_set_visible(x_axis, LXW_TRUE);
- *     chart_axis_major_gridlines_set_visible(y_axis, LXW_TRUE);
- * @endcode
- *
- * Note, the axis pointer can also be accessed directly:
- *
- * @code
- *     // Equivalent to the above example, without function calls.
- *     chart_axis_major_gridlines_set_visible(chart->x_axis, LXW_TRUE);
- *     chart_axis_major_gridlines_set_visible(chart->y_axis, LXW_TRUE);
- * @endcode
- *
- * @return Pointer to the chart axis, or NULL if not found.
- */
-lxw_chart_axis *chart_axis_get(lxw_chart *chart,
-                               lxw_chart_axis_type axis_type);
-
-/**
- * @brief Set the name caption of the an axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param name The name caption of the axis.
- *
- * The `%chart_axis_set_name()` function sets the name (also known as title or
- * caption) for an axis. It can be used for the X or Y axes. The name is
- * displayed below an X axis and to the side of a Y axis.
- *
- * @code
- *     chart_axis_set_name(chart->x_axis, "Earnings per Quarter");
- *     chart_axis_set_name(chart->y_axis, "US Dollars (Millions)");
- * @endcode
- *
- * @image html chart_axis_set_name.png
- *
- * The name parameter can also be a formula such as `=Sheet1!$A$1` to point to
- * a cell in the workbook that contains the name:
- *
- * @code
- *     chart_axis_set_name(chart->x_axis, "=Sheet1!$B1$1");
- * @endcode
- *
- * See also the `chart_axis_set_name_range()` function to see how to set the
- * name formula programmatically.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_name(lxw_chart_axis *axis, const char *name);
-
-/**
- * @brief Set a chart axis name formula using row and column values.
- *
- * @param axis      A pointer to a chart #lxw_chart_axis object.
- * @param sheetname The name of the worksheet that contains the cell range.
- * @param row       The zero indexed row number of the range.
- * @param col       The zero indexed column number of the range.
- *
- * The `%chart_axis_set_name_range()` function can be used to set an axis name
- * range and is an alternative to using `chart_axis_set_name()` and a string
- * formula:
- *
- * @code
- *     chart_axis_set_name_range(chart->x_axis, "Sheet1", 1, 0);
- *     chart_axis_set_name_range(chart->y_axis, "Sheet1", 2, 0);
- * @endcode
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname,
-                               lxw_row_t row, lxw_col_t col);
-
-/**
- * @brief Set the font properties for a chart axis name.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param font A pointer to a chart #lxw_chart_font font struct.
- *
- * The `%chart_axis_set_name_font()` function is used to set the font of an
- * axis name:
- *
- * @code
- *     lxw_chart_font font = {.bold = LXW_TRUE, .color = LXW_COLOR_BLUE};
- *
- *     chart_axis_set_name(chart->x_axis, "Yearly data");
- *     chart_axis_set_name_font(chart->x_axis, &font);
- * @endcode
- *
- * @image html chart_axis_set_name_font.png
- *
- * For more information see @ref chart_fonts.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_name_font(lxw_chart_axis *axis, lxw_chart_font *font);
-
-/**
- * @brief Set the font properties for the numbers of a chart axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param font A pointer to a chart #lxw_chart_font font struct.
- *
- * The `%chart_axis_set_num_font()` function is used to set the font of the
- * numbers on an axis:
- *
- * @code
- *     lxw_chart_font font = {.bold = LXW_TRUE, .color = LXW_COLOR_BLUE};
- *
- *     chart_axis_set_num_font(chart->x_axis, &font1);
- * @endcode
- *
- * @image html chart_axis_set_num_font.png
- *
- * For more information see @ref chart_fonts.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_num_font(lxw_chart_axis *axis, lxw_chart_font *font);
-
-/**
- * @brief Set the number format for a chart axis.
- *
- * @param axis       A pointer to a chart #lxw_chart_axis object.
- * @param num_format The number format string.
- *
- * The `%chart_axis_set_num_format()` function is used to set the format of
- * the numbers on an axis:
- *
- * @code
- *     chart_axis_set_num_format(chart->x_axis, "0.00%");
- *     chart_axis_set_num_format(chart->y_axis, "$#,##0.00");
- * @endcode
- *
- * The number format is similar to the Worksheet Cell Format num_format,
- * see `format_set_num_format()`.
- *
- * @image html chart_axis_num_format.png
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_num_format(lxw_chart_axis *axis, const char *num_format);
-
-/**
- * @brief Set the line properties for a chart axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param line A #lxw_chart_line struct.
- *
- * Set the line properties of a chart axis:
- *
- * @code
- *     // Hide the Y axis.
- *     lxw_chart_line line = {.none = LXW_TRUE};
- *
- *     chart_axis_set_line(chart->y_axis, &line);
- * @endcode
- *
- * @image html chart_axis_set_line.png
- *
- * For more information see @ref chart_lines.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_line(lxw_chart_axis *axis, lxw_chart_line *line);
-
-/**
- * @brief Set the fill properties for a chart axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param fill A #lxw_chart_fill struct.
- *
- * Set the fill properties of a chart axis:
- *
- * @code
- *     lxw_chart_fill fill = {.color = LXW_COLOR_YELLOW};
- *
- *     chart_axis_set_fill(chart->y_axis, &fill);
- * @endcode
- *
- * @image html chart_axis_set_fill.png
- *
- * For more information see @ref chart_fills.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_fill(lxw_chart_axis *axis, lxw_chart_fill *fill);
-
-/**
- * @brief Set the pattern properties for a chart axis.
- *
- * @param axis    A pointer to a chart #lxw_chart_axis object.
- * @param pattern A #lxw_chart_pattern struct.
- *
- * Set the pattern properties of a chart axis:
- *
- * @code
- *     chart_axis_set_pattern(chart->y_axis, &pattern);
- * @endcode
- *
- * For more information see #lxw_chart_pattern_type and @ref chart_patterns.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_pattern(lxw_chart_axis *axis, lxw_chart_pattern *pattern);
-
-/**
- * @brief Reverse the order of the axis categories or values.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- *
- * Reverse the order of the axis categories or values:
- *
- * @code
- *     chart_axis_set_reverse(chart->x_axis);
- * @endcode
- *
- * @image html chart_reverse.png
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_reverse(lxw_chart_axis *axis);
-
-/**
- * @brief Set the position that the axis will cross the opposite axis.
- *
- * @param axis  A pointer to a chart #lxw_chart_axis object.
- * @param value The category or value that the axis crosses at.
- *
- * Set the position that the axis will cross the opposite axis:
- *
- * @code
- *     chart_axis_set_crossing(chart->x_axis, 3);
- *     chart_axis_set_crossing(chart->y_axis, 8);
- * @endcode
- *
- * @image html chart_crossing1.png
- *
- * If crossing is omitted (the default) the crossing will be set automatically
- * by Excel based on the chart data.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_crossing(lxw_chart_axis *axis, double value);
-
-/**
- * @brief Set the opposite axis crossing position as the axis maximum.
- *
- * @param axis  A pointer to a chart #lxw_chart_axis object.
- *
- * Set the position that the opposite axis will cross as the axis maximum.
- * The default axis crossing position is generally the axis minimum so this
- * function can be used to reverse the location of the axes without reversing
- * the number sequence:
- *
- * @code
- *     chart_axis_set_crossing_max(chart->x_axis);
- *     chart_axis_set_crossing_max(chart->y_axis);
- * @endcode
- *
- * @image html chart_crossing2.png
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_crossing_max(lxw_chart_axis *axis);
-
-/**
- * @brief Turn off/hide an axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- *
- * Turn off, hide, a chart axis:
- *
- * @code
- *     chart_axis_off(chart->x_axis);
- * @endcode
- *
- * @image html chart_axis_off.png
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_off(lxw_chart_axis *axis);
-
-/**
- * @brief Position a category axis on or between the axis tick marks.
- *
- * @param axis     A pointer to a chart #lxw_chart_axis object.
- * @param position A #lxw_chart_axis_tick_position value.
- *
- * Position a category axis horizontally on, or between, the axis tick marks.
- *
- * There are two allowable values:
- *
- * - #LXW_CHART_AXIS_POSITION_ON_TICK
- * - #LXW_CHART_AXIS_POSITION_BETWEEN
- *
- * @code
- *     chart_axis_set_position(chart->x_axis, LXW_CHART_AXIS_POSITION_BETWEEN);
- * @endcode
- *
- * @image html chart_axis_set_position.png
- *
- * **Axis types**: This function is applicable to category axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_position(lxw_chart_axis *axis, uint8_t position);
-
-/**
- * @brief Position the axis labels.
- *
- * @param axis     A pointer to a chart #lxw_chart_axis object.
- * @param position A #lxw_chart_axis_label_position value.
- *
- * Position the axis labels for the chart. The labels are the numbers, or
- * strings or dates, on the axis that indicate the categories or values of
- * the axis.
- *
- * For example:
- *
- * @code
- *     chart_axis_set_label_position(chart->x_axis, LXW_CHART_AXIS_LABEL_POSITION_HIGH);
-       chart_axis_set_label_position(chart->y_axis, LXW_CHART_AXIS_LABEL_POSITION_HIGH);
- * @endcode
- *
- * @image html chart_label_position2.png
- *
- * The allowable values:
- *
- * - #LXW_CHART_AXIS_LABEL_POSITION_NEXT_TO - The default.
- * - #LXW_CHART_AXIS_LABEL_POSITION_HIGH - Also right for vertical axes.
- * - #LXW_CHART_AXIS_LABEL_POSITION_LOW - Also left for vertical axes.
- * - #LXW_CHART_AXIS_LABEL_POSITION_NONE
- *
- * @image html chart_label_position1.png
- *
- * The #LXW_CHART_AXIS_LABEL_POSITION_NONE turns off the axis labels. This
- * is slightly different from `chart_axis_off()` which also turns off the
- * labels but also turns off tick marks.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_label_position(lxw_chart_axis *axis, uint8_t position);
-
-/**
- * @brief Set the minimum value for a chart axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param min  Minimum value for chart axis. Value axes only.
- *
- * Set the minimum value for the axis range.
- *
- * @code
- *     chart_axis_set_min(chart->y_axis, -4);
- *     chart_axis_set_max(chart->y_axis, 21);
- * @endcode
- *
- * @image html chart_max_min.png
- *
- * **Axis types**: This function is applicable to value and date axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_min(lxw_chart_axis *axis, double min);
-
-/**
- * @brief Set the maximum value for a chart axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param max  Maximum value for chart axis. Value axes only.
- *
- * Set the maximum value for the axis range.
- *
- * @code
- *     chart_axis_set_min(chart->y_axis, -4);
- *     chart_axis_set_max(chart->y_axis, 21);
- * @endcode
- *
- * See the above image.
- *
- * **Axis types**: This function is applicable to value and date axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_max(lxw_chart_axis *axis, double max);
-
-/**
- * @brief Set the log base of the axis range.
- *
- * @param axis     A pointer to a chart #lxw_chart_axis object.
- * @param log_base The log base for value axis. Value axes only.
- *
- * Set the log base for the axis:
- *
- * @code
- *     chart_axis_set_log_base(chart->y_axis, 10);
- * @endcode
- *
- * @image html chart_log_base.png
- *
- * The allowable range of values for the log base in Excel is between 2 and
- * 1000.
- *
- * **Axis types**: This function is applicable to value axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_log_base(lxw_chart_axis *axis, uint16_t log_base);
-
-/**
- * @brief Set the major axis tick mark type.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param type The tick mark type, defined by #lxw_chart_tick_mark.
- *
- * Set the type of the major axis tick mark:
- *
- * @code
- *     chart_axis_set_major_tick_mark(chart->x_axis, LXW_CHART_AXIS_TICK_MARK_CROSSING);
- *     chart_axis_set_minor_tick_mark(chart->x_axis, LXW_CHART_AXIS_TICK_MARK_INSIDE);
- *
- *     chart_axis_set_major_tick_mark(chart->x_axis, LXW_CHART_AXIS_TICK_MARK_OUTSIDE);
- *     chart_axis_set_minor_tick_mark(chart->y_axis, LXW_CHART_AXIS_TICK_MARK_INSIDE);
- *
- *     // Hide the default gridlines so the tick marks are visible.
- *     chart_axis_major_gridlines_set_visible(chart->y_axis, LXW_FALSE);
- * @endcode
- *
- * @image html chart_tick_marks.png
- *
- * The tick mark types are:
- *
- * - #LXW_CHART_AXIS_TICK_MARK_NONE
- * - #LXW_CHART_AXIS_TICK_MARK_INSIDE
- * - #LXW_CHART_AXIS_TICK_MARK_OUTSIDE
- * - #LXW_CHART_AXIS_TICK_MARK_CROSSING
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_major_tick_mark(lxw_chart_axis *axis, uint8_t type);
-
-/**
- * @brief Set the minor axis tick mark type.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param type The tick mark type, defined by #lxw_chart_tick_mark.
- *
- * Set the type of the minor axis tick mark:
- *
- * @code
- *     chart_axis_set_minor_tick_mark(chart->x_axis, LXW_CHART_AXIS_TICK_MARK_INSIDE);
- * @endcode
- *
- * See the image and example above.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_minor_tick_mark(lxw_chart_axis *axis, uint8_t type);
-
-/**
- * @brief Set the interval between category values.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param unit The interval between the categories.
- *
- * Set the interval between the category values. The default interval is 1
- * which gives the intervals shown in the charts above:
- *
- *     1, 2, 3, 4, 5, etc.
- *
- * Setting it to 2 gives:
- *
- *     1, 3, 5, 7, etc.
- *
- * For example:
- *
- * @code
- *     chart_axis_set_interval_unit(chart->x_axis, 2);
- * @endcode
- *
- * @image html chart_set_interval1.png
- *
- * **Axis types**: This function is applicable to category and date axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_interval_unit(lxw_chart_axis *axis, uint16_t unit);
-
-/**
- * @brief Set the interval between category tick marks.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param unit The interval between the category ticks.
- *
- * Set the interval between the category tick marks. The default interval is 1
- * between each category but it can be set to other integer values:
- *
- * @code
- *     chart_axis_set_interval_tick(chart->x_axis, 2);
- * @endcode
- *
- * @image html chart_set_interval2.png
- *
- * **Axis types**: This function is applicable to category and date axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_interval_tick(lxw_chart_axis *axis, uint16_t unit);
-
-/**
- * @brief Set the increment of the major units in the axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param unit The increment of the major units.
- *
- * Set the increment of the major units in the axis range.
- *
- * @code
- *     // Turn on the minor gridline (it is off by default).
- *     chart_axis_minor_gridlines_set_visible(chart->y_axis, LXW_TRUE);
- *
- *     chart_axis_set_major_unit(chart->y_axis, 4);
- *     chart_axis_set_minor_unit(chart->y_axis, 2);
- * @endcode
- *
- * @image html chart_set_major_units.png
- *
- * **Axis types**: This function is applicable to value and date axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_major_unit(lxw_chart_axis *axis, double unit);
-
-/**
- * @brief Set the increment of the minor units in the axis.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param unit The increment of the minor units.
- *
- * Set the increment of the minor units in the axis range.
- *
- * @code
- *     chart_axis_set_minor_unit(chart->y_axis, 2);
- * @endcode
- *
- * See the image above
- *
- * **Axis types**: This function is applicable to value and date axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_minor_unit(lxw_chart_axis *axis, double unit);
-
-/**
- * @brief Set the display units for a value axis.
- *
- * @param axis  A pointer to a chart #lxw_chart_axis object.
- * @param units The display units: #lxw_chart_axis_display_unit.
- *
- * Set the display units for the axis. This can be useful if the axis numbers
- * are very large but you don't want to represent them in scientific notation:
- *
- * @code
- *     chart_axis_set_display_units(chart->x_axis, LXW_CHART_AXIS_UNITS_THOUSANDS);
- *     chart_axis_set_display_units(chart->y_axis, LXW_CHART_AXIS_UNITS_MILLIONS);
- * @endcode
- *
- * @image html chart_display_units.png
- *
- * **Axis types**: This function is applicable to value axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_display_units(lxw_chart_axis *axis, uint8_t units);
-
-/**
- * @brief Turn on/off the display units for a value axis.
-
- * @param axis    A pointer to a chart #lxw_chart_axis object.
- * @param visible Turn off/on the display units. (0/1)
- *
- * Turn on or off the display units for the axis. This option is set on
- * automatically by `chart_axis_set_display_units()`.
- *
- * @code
- *     chart_axis_set_display_units_visible(chart->y_axis, LXW_TRUE);
- * @endcode
- *
- * **Axis types**: This function is applicable to value axes only.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_set_display_units_visible(lxw_chart_axis *axis,
-                                          uint8_t visible);
-
-/**
- * @brief Turn on/off the major gridlines for an axis.
- *
- * @param axis    A pointer to a chart #lxw_chart_axis object.
- * @param visible Turn off/on the major gridline. (0/1)
- *
- * Turn on or off the major gridlines for an X or Y axis. In most Excel charts
- * the Y axis major gridlines are on by default and the X axis major
- * gridlines are off by default.
- *
- * Example:
- *
- * @code
- *     // Reverse the normal visible/hidden gridlines for a column chart.
- *     chart_axis_major_gridlines_set_visible(chart->x_axis, LXW_TRUE);
- *     chart_axis_major_gridlines_set_visible(chart->y_axis, LXW_FALSE);
- * @endcode
- *
- * @image html chart_gridline1.png
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_major_gridlines_set_visible(lxw_chart_axis *axis,
-                                            uint8_t visible);
-
-/**
- * @brief Turn on/off the minor gridlines for an axis.
- *
- * @param axis    A pointer to a chart #lxw_chart_axis object.
- * @param visible Turn off/on the minor gridline. (0/1)
- *
- * Turn on or off the minor gridlines for an X or Y axis. In most Excel charts
- * the X and Y axis minor gridlines are off by default.
- *
- * Example, turn on all major and minor gridlines:
- *
- * @code
- *     chart_axis_major_gridlines_set_visible(chart->x_axis, LXW_TRUE);
- *     chart_axis_minor_gridlines_set_visible(chart->x_axis, LXW_TRUE);
- *     chart_axis_major_gridlines_set_visible(chart->y_axis, LXW_TRUE);
- *     chart_axis_minor_gridlines_set_visible(chart->y_axis, LXW_TRUE);
- * @endcode
- *
- * @image html chart_gridline2.png
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_minor_gridlines_set_visible(lxw_chart_axis *axis,
-                                            uint8_t visible);
-
-/**
- * @brief Set the line properties for the chart axis major gridlines.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param line A #lxw_chart_line struct.
- *
- * Format the line properties of the major gridlines of a chart:
- *
- * @code
- *     lxw_chart_line line1 = {.color = LXW_COLOR_RED,
- *                             .width = 0.5,
- *                             .dash_type = LXW_CHART_LINE_DASH_SQUARE_DOT};
- *
- *     lxw_chart_line line2 = {.color = LXW_COLOR_YELLOW};
- *
- *     lxw_chart_line line3 = {.width = 1.25,
- *                             .dash_type = LXW_CHART_LINE_DASH_DASH};
- *
- *     lxw_chart_line line4 = {.color =  0x00B050};
- *
- *     chart_axis_major_gridlines_set_line(chart->x_axis, &line1);
- *     chart_axis_minor_gridlines_set_line(chart->x_axis, &line2);
- *     chart_axis_major_gridlines_set_line(chart->y_axis, &line3);
- *     chart_axis_minor_gridlines_set_line(chart->y_axis, &line4);
- * @endcode
- *
- * @image html chart_gridline3.png
- *
- * For more information see @ref chart_lines.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_major_gridlines_set_line(lxw_chart_axis *axis,
-                                         lxw_chart_line *line);
-
-/**
- * @brief Set the line properties for the chart axis minor gridlines.
- *
- * @param axis A pointer to a chart #lxw_chart_axis object.
- * @param line A #lxw_chart_line struct.
- *
- * Format the line properties of the minor gridlines of a chart, see the
- * example above.
- *
- * For more information see @ref chart_lines.
- *
- * **Axis types**: This function is applicable to to all axes types.
- *                 See @ref ww_charts_axes.
- */
-void chart_axis_minor_gridlines_set_line(lxw_chart_axis *axis,
-                                         lxw_chart_line *line);
-
-/**
- * @brief Set the title of the chart.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param name  The chart title name.
- *
- * The `%chart_title_set_name()` function sets the name (title) for the
- * chart. The name is displayed above the chart.
- *
- * @code
- *     chart_title_set_name(chart, "Year End Results");
- * @endcode
- *
- * @image html chart_title_set_name.png
- *
- * The name parameter can also be a formula such as `=Sheet1!$A$1` to point to
- * a cell in the workbook that contains the name:
- *
- * @code
- *     chart_title_set_name(chart, "=Sheet1!$B1$1");
- * @endcode
- *
- * See also the `chart_title_set_name_range()` function to see how to set the
- * name formula programmatically.
- *
- * The Excel default is to have no chart title.
- */
-void chart_title_set_name(lxw_chart *chart, const char *name);
-
-/**
- * @brief Set a chart title formula using row and column values.
- *
- * @param chart     Pointer to a lxw_chart instance to be configured.
- * @param sheetname The name of the worksheet that contains the cell range.
- * @param row       The zero indexed row number of the range.
- * @param col       The zero indexed column number of the range.
- *
- * The `%chart_title_set_name_range()` function can be used to set a chart
- * title range and is an alternative to using `chart_title_set_name()` and a
- * string formula:
- *
- * @code
- *     chart_title_set_name_range(chart, "Sheet1", 1, 0);
- * @endcode
- */
-void chart_title_set_name_range(lxw_chart *chart, const char *sheetname,
-                                lxw_row_t row, lxw_col_t col);
-
-/**
- * @brief  Set the font properties for a chart title.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param font  A pointer to a chart #lxw_chart_font font struct.
- *
- * The `%chart_title_set_name_font()` function is used to set the font of a
- * chart title:
- *
- * @code
- *     lxw_chart_font font = {.bold = LXW_TRUE, .color = LXW_COLOR_BLUE};
- *
- *     chart_title_set_name(chart, "Year End Results");
- *     chart_title_set_name_font(chart, &font);
- * @endcode
- *
- * @image html chart_title_set_name_font.png
- *
- * For more information see @ref chart_fonts.
- */
-void chart_title_set_name_font(lxw_chart *chart, lxw_chart_font *font);
-
-/**
- * @brief Turn off an automatic chart title.
- *
- * @param chart  Pointer to a lxw_chart instance to be configured.
- *
- * In general in Excel a chart title isn't displayed unless the user
- * explicitly adds one. However, Excel adds an automatic chart title to charts
- * with a single series and a user defined series name. The
- * `chart_title_off()` function allows you to turn off this automatic chart
- * title:
- *
- * @code
- *     chart_title_off(chart);
- * @endcode
- */
-void chart_title_off(lxw_chart *chart);
-
-/**
- * @brief Set the position of the chart legend.
- *
- * @param chart    Pointer to a lxw_chart instance to be configured.
- * @param position The #lxw_chart_legend_position value for the legend.
- *
- * The `%chart_legend_set_position()` function is used to set the chart
- * legend to one of the #lxw_chart_legend_position values:
- *
- *     LXW_CHART_LEGEND_NONE
- *     LXW_CHART_LEGEND_RIGHT
- *     LXW_CHART_LEGEND_LEFT
- *     LXW_CHART_LEGEND_TOP
- *     LXW_CHART_LEGEND_BOTTOM
- *     LXW_CHART_LEGEND_OVERLAY_RIGHT
- *     LXW_CHART_LEGEND_OVERLAY_LEFT
- *
- * For example:
- *
- * @code
- *     chart_legend_set_position(chart, LXW_CHART_LEGEND_BOTTOM);
- * @endcode
- *
- * @image html chart_legend_bottom.png
- *
- * This function can also be used to turn off a chart legend:
- *
- * @code
- *     chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
- * @endcode
- *
- * @image html chart_legend_none.png
- *
- */
-void chart_legend_set_position(lxw_chart *chart, uint8_t position);
-
-/**
- * @brief Set the font properties for a chart legend.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param font  A pointer to a chart #lxw_chart_font font struct.
- *
- * The `%chart_legend_set_font()` function is used to set the font of a
- * chart legend:
- *
- * @code
- *     lxw_chart_font font = {.bold = LXW_TRUE, .color = LXW_COLOR_BLUE};
- *
- *     chart_legend_set_font(chart, &font);
- * @endcode
- *
- * @image html chart_legend_set_font.png
- *
- * For more information see @ref chart_fonts.
- */
-void chart_legend_set_font(lxw_chart *chart, lxw_chart_font *font);
-
-/**
- * @brief Remove one or more series from the the legend.
- *
- * @param chart         Pointer to a lxw_chart instance to be configured.
- * @param delete_series An array of zero-indexed values to delete from series.
- *
- * @return A #lxw_error.
- *
- * The `%chart_legend_delete_series()` function allows you to remove/hide one
- * or more series in a chart legend (the series will still display on the chart).
- *
- * This function takes an array of one or more zero indexed series
- * numbers. The array should be terminated with -1.
- *
- * For example to remove the first and third zero-indexed series from the
- * legend of a chart with 3 series:
- *
- * @code
- *     int16_t series[] = {0, 2, -1};
- *
- *     chart_legend_delete_series(chart, series);
- * @endcode
- *
- * @image html chart_legend_delete.png
- */
-lxw_error chart_legend_delete_series(lxw_chart *chart,
-                                     int16_t delete_series[]);
-
-/**
- * @brief Set the line properties for a chartarea.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param line  A #lxw_chart_line struct.
- *
- * Set the line/border properties of a chartarea. In Excel the chartarea
- * is the background area behind the chart:
- *
- * @code
- *     lxw_chart_line line = {.none  = LXW_TRUE};
- *     lxw_chart_fill fill = {.color = LXW_COLOR_RED};
- *
- *     chart_chartarea_set_line(chart, &line);
- *     chart_chartarea_set_fill(chart, &fill);
- * @endcode
- *
- * @image html chart_chartarea.png
- *
- * For more information see @ref chart_lines.
- */
-void chart_chartarea_set_line(lxw_chart *chart, lxw_chart_line *line);
-
-/**
- * @brief Set the fill properties for a chartarea.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param fill  A #lxw_chart_fill struct.
- *
- * Set the fill properties of a chartarea:
- *
- * @code
- *     chart_chartarea_set_fill(chart, &fill);
- * @endcode
- *
- * See the example and image above.
- *
- * For more information see @ref chart_fills.
- */
-void chart_chartarea_set_fill(lxw_chart *chart, lxw_chart_fill *fill);
-
-/**
- * @brief Set the pattern properties for a chartarea.
- *
- * @param chart   Pointer to a lxw_chart instance to be configured.
- * @param pattern A #lxw_chart_pattern struct.
- *
- * Set the pattern properties of a chartarea:
- *
- * @code
- *     chart_chartarea_set_pattern(series1, &pattern);
- * @endcode
- *
- * For more information see #lxw_chart_pattern_type and @ref chart_patterns.
- */
-void chart_chartarea_set_pattern(lxw_chart *chart,
-                                 lxw_chart_pattern *pattern);
-
-/**
- * @brief Set the line properties for a plotarea.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param line  A #lxw_chart_line struct.
- *
- * Set the line/border properties of a plotarea. In Excel the plotarea is
- * the area between the axes on which the chart series are plotted:
- *
- * @code
- *     lxw_chart_line line = {.color     = LXW_COLOR_RED,
- *                            .width     = 2,
- *                            .dash_type = LXW_CHART_LINE_DASH_DASH};
- *     lxw_chart_fill fill = {.color     = 0xFFFFC2};
- *
- *     chart_plotarea_set_line(chart, &line);
- *     chart_plotarea_set_fill(chart, &fill);
- *
- * @endcode
- *
- * @image html chart_plotarea.png
- *
- * For more information see @ref chart_lines.
- */
-void chart_plotarea_set_line(lxw_chart *chart, lxw_chart_line *line);
-
-/**
- * @brief Set the fill properties for a plotarea.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param fill  A #lxw_chart_fill struct.
- *
- * Set the fill properties of a plotarea:
- *
- * @code
- *     chart_plotarea_set_fill(chart, &fill);
- * @endcode
- *
- * See the example and image above.
- *
- * For more information see @ref chart_fills.
- */
-void chart_plotarea_set_fill(lxw_chart *chart, lxw_chart_fill *fill);
-
-/**
- * @brief Set the pattern properties for a plotarea.
- *
- * @param chart   Pointer to a lxw_chart instance to be configured.
- * @param pattern A #lxw_chart_pattern struct.
- *
- * Set the pattern properties of a plotarea:
- *
- * @code
- *     chart_plotarea_set_pattern(series1, &pattern);
- * @endcode
- *
- * For more information see #lxw_chart_pattern_type and @ref chart_patterns.
- */
-void chart_plotarea_set_pattern(lxw_chart *chart, lxw_chart_pattern *pattern);
-
-/**
- * @brief Set the chart style type.
- *
- * @param chart    Pointer to a lxw_chart instance to be configured.
- * @param style_id An index representing the chart style, 1 - 48.
- *
- * The `%chart_set_style()` function is used to set the style of the chart to
- * one of the 48 built-in styles available on the "Design" tab in Excel 2007:
- *
- * @code
- *     chart_set_style(chart, 37)
- * @endcode
- *
- * @image html chart_style.png
- *
- * The style index number is counted from 1 on the top left in the Excel
- * dialog. The default style is 2.
- *
- * **Note:**
- *
- * In Excel 2013 the Styles section of the "Design" tab in Excel shows what
- * were referred to as "Layouts" in previous versions of Excel. These layouts
- * are not defined in the file format. They are a collection of modifications
- * to the base chart type. They can not be defined by the `chart_set_style()``
- * function.
- *
- */
-void chart_set_style(lxw_chart *chart, uint8_t style_id);
-
-/**
- * @brief Turn on a data table below the horizontal axis.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- *
- * The `%chart_set_table()` function adds a data table below the horizontal
- * axis with the data used to plot the chart:
- *
- * @code
- *     // Turn on the data table with default options.
- *     chart_set_table(chart);
- * @endcode
- *
- * @image html chart_data_table1.png
- *
- * The data table can only be shown with Bar, Column, Line and Area charts.
- *
- */
-void chart_set_table(lxw_chart *chart);
-
-/**
- * @brief Turn on/off grid options for a chart data table.
- *
- * @param chart       Pointer to a lxw_chart instance to be configured.
- * @param horizontal  Turn on/off the horizontal grid lines in the table.
- * @param vertical    Turn on/off the vertical grid lines in the table.
- * @param outline     Turn on/off the outline lines in the table.
- * @param legend_keys Turn on/off the legend keys in the table.
- *
- * The `%chart_set_table_grid()` function turns on/off grid options for a
- * chart data table. The data table grid options in Excel are shown in the
- * dialog below:
- *
- * @image html chart_data_table3.png
- *
- * These options can be passed to the `%chart_set_table_grid()` function.
- * The values for a default chart are:
- *
- * - `horizontal`: On.
- * - `vertical`: On.
- * - `outline`:  On.
- * - `legend_keys`: Off.
- *
- * Example:
- *
- * @code
- *     // Turn on the data table with default options.
- *     chart_set_table(chart);
- *
- *     // Turn on all grid lines and the grid legend.
- *     chart_set_table_grid(chart, LXW_TRUE, LXW_TRUE, LXW_TRUE, LXW_TRUE);
- *
- *     // Turn off the legend since it is show in the table.
- *     chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
- *
- * @endcode
- *
- * @image html chart_data_table2.png
- *
- * The data table can only be shown with Bar, Column, Line and Area charts.
- *
- */
-void chart_set_table_grid(lxw_chart *chart, uint8_t horizontal,
-                          uint8_t vertical, uint8_t outline,
-                          uint8_t legend_keys);
-
-void chart_set_table_font(lxw_chart *chart, lxw_chart_font *font);
-
-/**
- * @brief Turn on up-down bars for the chart.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- *
- * The `%chart_set_up_down_bars()` function adds Up-Down bars to Line charts
- * to indicate the difference between the first and last data series:
- *
- * @code
- *     chart_set_up_down_bars(chart);
- * @endcode
- *
- * @image html chart_data_tools4.png
- *
- * Up-Down bars are only available in Line charts. By default Up-Down bars are
- * black and white like in the above example. To format the border or fill
- * of the bars see the `chart_set_up_down_bars_format()` function below.
- */
-void chart_set_up_down_bars(lxw_chart *chart);
-
-/**
- * @brief Turn on up-down bars for the chart, with formatting.
- *
- * @param chart         Pointer to a lxw_chart instance to be configured.
- * @param up_bar_line   A #lxw_chart_line struct for the up-bar border.
- * @param up_bar_fill   A #lxw_chart_fill struct for the up-bar fill.
- * @param down_bar_line A #lxw_chart_line struct for the down-bar border.
- * @param down_bar_fill A #lxw_chart_fill struct for the down-bar fill.
- *
- * The `%chart_set_up_down_bars_format()` function adds Up-Down bars to Line
- * charts to indicate the difference between the first and last data series.
- * It also allows the up and down bars to be formatted:
- *
- * @code
- *     lxw_chart_line line      = {.color = LXW_COLOR_BLACK};
- *     lxw_chart_fill up_fill   = {.color = 0x00B050};
- *     lxw_chart_fill down_fill = {.color = LXW_COLOR_RED};
- *
- *     chart_set_up_down_bars_format(chart, &line, &up_fill, &line, &down_fill);
- * @endcode
- *
- * @image html chart_up_down_bars.png
- *
- * Up-Down bars are only available in Line charts.
- * For more format information  see @ref chart_lines and @ref chart_fills.
- */
-void chart_set_up_down_bars_format(lxw_chart *chart,
-                                   lxw_chart_line *up_bar_line,
-                                   lxw_chart_fill *up_bar_fill,
-                                   lxw_chart_line *down_bar_line,
-                                   lxw_chart_fill *down_bar_fill);
-
-/**
- * @brief Turn on and format Drop Lines for a chart.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param line  A #lxw_chart_line struct.
- *
- * The `%chart_set_drop_lines()` function adds Drop Lines to charts to
- * show the Category value of points in the data:
- *
- * @code
- *     chart_set_drop_lines(chart, NULL);
- * @endcode
- *
- * @image html chart_data_tools6.png
- *
- * It is possible to format the Drop Line line properties if required:
- *
- * @code
- *     lxw_chart_line line = {.color     = LXW_COLOR_RED,
- *                            .dash_type = LXW_CHART_LINE_DASH_SQUARE_DOT};
- *
- *     chart_set_drop_lines(chart, &line);
- * @endcode
- *
- * Drop Lines are only available in Line and Area charts.
- * For more format information see @ref chart_lines.
- */
-void chart_set_drop_lines(lxw_chart *chart, lxw_chart_line *line);
-
-/**
- * @brief Turn on and format high-low Lines for a chart.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param line  A #lxw_chart_line struct.
- *
- * The `%chart_set_high_low_lines()` function adds High-Low Lines to charts
- * to show the Category value of points in the data:
- *
- * @code
- *     chart_set_high_low_lines(chart, NULL);
- * @endcode
- *
- * @image html chart_data_tools5.png
- *
- * It is possible to format the High-Low Line line properties if required:
- *
- * @code
- *     lxw_chart_line line = {.color     = LXW_COLOR_RED,
- *                            .dash_type = LXW_CHART_LINE_DASH_SQUARE_DOT};
- *
- *     chart_set_high_low_lines(chart, &line);
- * @endcode
- *
- * High-Low Lines are only available in Line charts.
- * For more format information see @ref chart_lines.
- */
-void chart_set_high_low_lines(lxw_chart *chart, lxw_chart_line *line);
-
-/**
- * @brief Set the overlap between series in a Bar/Column chart.
- *
- * @param chart   Pointer to a lxw_chart instance to be configured.
- * @param overlap The overlap between the series. -100 to 100.
- *
- * The `%chart_set_series_overlap()` function sets the overlap between series
- * in Bar and Column charts.
- *
- * @code
- *     chart_set_series_overlap(chart, -50);
- * @endcode
- *
- * @image html chart_overlap.png
- *
- * The overlap value must be in the range `0 <= overlap <= 500`.
- * The default value is 0.
- *
- * This option is only available for Bar/Column charts.
- */
-void chart_set_series_overlap(lxw_chart *chart, int8_t overlap);
-
-/**
- * @brief Set the gap between series in a Bar/Column chart.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param gap   The gap between the series.  0 to 500.
- *
- * The `%chart_set_series_gap()` function sets the gap between series in
- * Bar and Column charts.
- *
- * @code
- *     chart_set_series_gap(chart, 400);
- * @endcode
- *
- * @image html chart_gap.png
- *
- * The gap value must be in the range `0 <= gap <= 500`. The default value
- * is 150.
- *
- * This option is only available for Bar/Column charts.
- */
-void chart_set_series_gap(lxw_chart *chart, uint16_t gap);
-
-/**
- * @brief Set the option for displaying blank data in a chart.
- *
- * @param chart    Pointer to a lxw_chart instance to be configured.
- * @param option The display option. A #lxw_chart_blank option.
- *
- * The `%chart_show_blanks_as()` function controls how blank data is displayed
- * in a chart:
- *
- * @code
- *     chart_show_blanks_as(chart, LXW_CHART_BLANKS_AS_CONNECTED);
- * @endcode
- *
- * The `option` parameter can have one of the following values:
- *
- * - #LXW_CHART_BLANKS_AS_GAP: Show empty chart cells as gaps in the data.
- *   This is the default option for Excel charts.
- * - #LXW_CHART_BLANKS_AS_ZERO: Show empty chart cells as zeros.
- * - #LXW_CHART_BLANKS_AS_CONNECTED: Show empty chart cells as connected.
- *   Only for charts with lines.
- */
-void chart_show_blanks_as(lxw_chart *chart, uint8_t option);
-
-/**
- * @brief Display data on charts from hidden rows or columns.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- *
- * Display data that is in hidden rows or columns on the chart:
- *
- * @code
- *     chart_show_hidden_data(chart);
- * @endcode
- */
-void chart_show_hidden_data(lxw_chart *chart);
-
-/**
- * @brief Set the Pie/Doughnut chart rotation.
- *
- * @param chart    Pointer to a lxw_chart instance to be configured.
- * @param rotation The angle of rotation.
- *
- * The `chart_set_rotation()` function is used to set the rotation of the
- * first segment of a Pie/Doughnut chart. This has the effect of rotating
- * the entire chart:
- *
- * @code
- *     chart_set_rotation(chart, 28);
- * @endcode
- *
- * The angle of rotation must be in the range `0 <= rotation <= 360`.
- *
- * This option is only available for Pie/Doughnut charts.
- *
- */
-void chart_set_rotation(lxw_chart *chart, uint16_t rotation);
-
-/**
- * @brief Set the Doughnut chart hole size.
- *
- * @param chart Pointer to a lxw_chart instance to be configured.
- * @param size  The hole size as a percentage.
- *
- * The `chart_set_hole_size()` function is used to set the hole size of a
- * Doughnut chart:
- *
- * @code
- *     chart_set_hole_size(chart, 33);
- * @endcode
- *
- * The hole size must be in the range `10 <= size <= 90`.
- *
- * This option is only available for Doughnut charts.
- *
- */
-void chart_set_hole_size(lxw_chart *chart, uint8_t size);
-
-lxw_error lxw_chart_add_data_cache(lxw_series_range *range, uint8_t *data,
-                                   uint16_t rows, uint8_t cols, uint8_t col);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _chart_xml_declaration(lxw_chart *chart);
-STATIC void _chart_write_legend(lxw_chart *chart);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_CHART_H__ */

+ 0 - 380
library/include/xlsxwriter/common.h

@@ -1,380 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- */
-
-/**
- * @file common.h
- *
- * @brief Common functions and defines for the libxlsxwriter library.
- *
- * <!-- Copyright 2014-2018, John McNamara, [email protected] -->
- *
- */
-#ifndef __LXW_COMMON_H__
-#define __LXW_COMMON_H__
-
-#include <time.h>
-#include "third_party/queue.h"
-#include "third_party/tree.h"
-
-#ifndef TESTING
-#define STATIC static
-#else
-#define STATIC
-#endif
-
-/** Integer data type to represent a row value. Equivalent to `uint32_t`.
- *
- * The maximum row in Excel is 1,048,576.
- */
-typedef uint32_t lxw_row_t;
-
-/** Integer data type to represent a column value. Equivalent to `uint16_t`.
- *
- * The maximum column in Excel is 16,384.
- */
-typedef uint16_t lxw_col_t;
-
-/** Boolean values used in libxlsxwriter. */
-enum lxw_boolean {
-    /** False value. */
-    LXW_FALSE,
-    /** True value. */
-    LXW_TRUE
-};
-
-/**
- * @brief Error codes from libxlsxwriter functions.
- *
- * See the `lxw_strerror()` function for an example of how to convert the
- * enum number to a descriptive error message string.
- */
-typedef enum lxw_error {
-
-    /** No error. */
-    LXW_NO_ERROR = 0,
-
-    /** Memory error, failed to malloc() required memory. */
-    LXW_ERROR_MEMORY_MALLOC_FAILED,
-
-    /** Error creating output xlsx file. Usually a permissions error. */
-    LXW_ERROR_CREATING_XLSX_FILE,
-
-    /** Error encountered when creating a tmpfile during file assembly. */
-    LXW_ERROR_CREATING_TMPFILE,
-
-    /** Zlib error with a file operation while creating xlsx file. */
-    LXW_ERROR_ZIP_FILE_OPERATION,
-
-    /** Zlib error when adding sub file to xlsx file. */
-    LXW_ERROR_ZIP_FILE_ADD,
-
-    /** Zlib error when closing xlsx file. */
-    LXW_ERROR_ZIP_CLOSE,
-
-    /** NULL function parameter ignored. */
-    LXW_ERROR_NULL_PARAMETER_IGNORED,
-
-    /** Function parameter validation error. */
-    LXW_ERROR_PARAMETER_VALIDATION,
-
-    /** Worksheet name exceeds Excel's limit of 31 characters. */
-    LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED,
-
-    /** Worksheet name contains invalid Excel character: '[]:*?/\\' */
-    LXW_ERROR_INVALID_SHEETNAME_CHARACTER,
-
-    /** Worksheet name is already in use. */
-    LXW_ERROR_SHEETNAME_ALREADY_USED,
-
-    /** Parameter exceeds Excel's limit of 32 characters. */
-    LXW_ERROR_32_STRING_LENGTH_EXCEEDED,
-
-    /** Parameter exceeds Excel's limit of 128 characters. */
-    LXW_ERROR_128_STRING_LENGTH_EXCEEDED,
-
-    /** Parameter exceeds Excel's limit of 255 characters. */
-    LXW_ERROR_255_STRING_LENGTH_EXCEEDED,
-
-    /** String exceeds Excel's limit of 32,767 characters. */
-    LXW_ERROR_MAX_STRING_LENGTH_EXCEEDED,
-
-    /** Error finding internal string index. */
-    LXW_ERROR_SHARED_STRING_INDEX_NOT_FOUND,
-
-    /** Worksheet row or column index out of range. */
-    LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE,
-
-    /** Maximum number of worksheet URLs (65530) exceeded. */
-    LXW_ERROR_WORKSHEET_MAX_NUMBER_URLS_EXCEEDED,
-
-    /** Couldn't read image dimensions or DPI. */
-    LXW_ERROR_IMAGE_DIMENSIONS,
-
-    LXW_MAX_ERRNO
-} lxw_error;
-
-/** @brief Struct to represent a date and time in Excel.
- *
- * Struct to represent a date and time in Excel. See @ref working_with_dates.
- */
-typedef struct lxw_datetime {
-
-    /** Year     : 1900 - 9999 */
-    int year;
-    /** Month    : 1 - 12 */
-    int month;
-    /** Day      : 1 - 31 */
-    int day;
-    /** Hour     : 0 - 23 */
-    int hour;
-    /** Minute   : 0 - 59 */
-    int min;
-    /** Seconds  : 0 - 59.999 */
-    double sec;
-
-} lxw_datetime;
-
-enum lxw_custom_property_types {
-    LXW_CUSTOM_NONE,
-    LXW_CUSTOM_STRING,
-    LXW_CUSTOM_DOUBLE,
-    LXW_CUSTOM_INTEGER,
-    LXW_CUSTOM_BOOLEAN,
-    LXW_CUSTOM_DATETIME
-};
-
-/* Excel sheetname max of 31 chars. */
-#define LXW_SHEETNAME_MAX         31
-
-/* Max with all worksheet chars 4xUTF-8 bytes + start and end quotes + \0. */
-#define LXW_MAX_SHEETNAME_LENGTH  ((LXW_SHEETNAME_MAX * 4) + 2 + 1)
-
-/* Max col string length. */
-#define LXW_MAX_COL_NAME_LENGTH   sizeof("$XFD")
-
-/* Max row string length. */
-#define LXW_MAX_ROW_NAME_LENGTH   sizeof("$1048576")
-
-/* Max cell string length. */
-#define LXW_MAX_CELL_NAME_LENGTH  sizeof("$XFWD$1048576")
-
-/* Max range: $XFWD$1048576:$XFWD$1048576\0 */
-#define LXW_MAX_CELL_RANGE_LENGTH (LXW_MAX_CELL_NAME_LENGTH * 2)
-
-/* Max range formula Sheet1!$A$1:$C$5$ style. */
-#define LXW_MAX_FORMULA_RANGE_LENGTH (LXW_MAX_SHEETNAME_LENGTH + LXW_MAX_CELL_RANGE_LENGTH)
-
-/* Datetime string length. */
-#define LXW_DATETIME_LENGTH       sizeof("2016-12-12T23:00:00Z")
-
-#define LXW_EPOCH_1900            0
-#define LXW_EPOCH_1904            1
-
-#define LXW_UINT32_T_LENGTH       sizeof("4294967296")
-#define LXW_FILENAME_LENGTH       128
-#define LXW_IGNORE                1
-
-#define LXW_SCHEMA_MS        "http://schemas.microsoft.com/office/2006/relationships"
-#define LXW_SCHEMA_ROOT      "http://schemas.openxmlformats.org"
-#define LXW_SCHEMA_DRAWING   LXW_SCHEMA_ROOT "/drawingml/2006"
-#define LXW_SCHEMA_OFFICEDOC LXW_SCHEMA_ROOT "/officeDocument/2006"
-#define LXW_SCHEMA_PACKAGE   LXW_SCHEMA_ROOT "/package/2006/relationships"
-#define LXW_SCHEMA_DOCUMENT  LXW_SCHEMA_ROOT "/officeDocument/2006/relationships"
-#define LXW_SCHEMA_CONTENT   LXW_SCHEMA_ROOT "/package/2006/content-types"
-
-#define LXW_ERROR(message)                      \
-    fprintf(stderr, "[ERROR][%s:%d]: " message "\n", __FILE__, __LINE__)
-
-#define LXW_MEM_ERROR()                         \
-    LXW_ERROR("Memory allocation failed.")
-
-#define GOTO_LABEL_ON_MEM_ERROR(pointer, label) \
-    if (!pointer) {                             \
-        LXW_MEM_ERROR();                        \
-        goto label;                             \
-    }
-
-#define RETURN_ON_MEM_ERROR(pointer, error)     \
-    if (!pointer) {                             \
-        LXW_MEM_ERROR();                        \
-        return error;                           \
-    }
-
-#define RETURN_VOID_ON_MEM_ERROR(pointer)       \
-    if (!pointer) {                             \
-        LXW_MEM_ERROR();                        \
-        return;                                 \
-    }
-
-#define RETURN_ON_ERROR(error)                  \
-    if (error)                                  \
-        return error;
-
-#define LXW_WARN(message)                       \
-    fprintf(stderr, "[WARNING]: " message "\n")
-
-/* We can't use variadic macros here since we support ANSI C. */
-#define LXW_WARN_FORMAT(message)                \
-    fprintf(stderr, "[WARNING]: " message "\n")
-
-#define LXW_WARN_FORMAT1(message, var)          \
-    fprintf(stderr, "[WARNING]: " message "\n", var)
-
-#define LXW_WARN_FORMAT2(message, var1, var2)    \
-    fprintf(stderr, "[WARNING]: " message "\n", var1, var2)
-
-/* Chart axis type checks. */
-#define LXW_WARN_CAT_AXIS_ONLY(function)                                   \
-    if (!axis->is_category) {                                              \
-        fprintf(stderr, "[WARNING]: "                                      \
-                function "() is only valid for category axes\n");          \
-       return;                                                             \
-    }
-
-#define LXW_WARN_VALUE_AXIS_ONLY(function)                                 \
-    if (!axis->is_value) {                                                 \
-        fprintf(stderr, "[WARNING]: "                                      \
-                function "() is only valid for value axes\n");             \
-       return;                                                             \
-    }
-
-#define LXW_WARN_DATE_AXIS_ONLY(function)                                  \
-    if (!axis->is_date) {                                                  \
-        fprintf(stderr, "[WARNING]: "                                      \
-                function "() is only valid for date axes\n");              \
-       return;                                                             \
-    }
-
-#define LXW_WARN_CAT_AND_DATE_AXIS_ONLY(function)                          \
-    if (!axis->is_category && !axis->is_date) {                            \
-        fprintf(stderr, "[WARNING]: "                                      \
-                function "() is only valid for category and date axes\n"); \
-       return;                                                             \
-    }
-
-#define LXW_WARN_VALUE_AND_DATE_AXIS_ONLY(function)                        \
-    if (!axis->is_value && !axis->is_date) {                               \
-        fprintf(stderr, "[WARNING]: "                                      \
-                function "() is only valid for value and date axes\n");    \
-       return;                                                             \
-    }
-
-#ifndef LXW_BIG_ENDIAN
-#define LXW_UINT32_NETWORK(n) ((((n) & 0xFF)       << 24) | \
-                               (((n) & 0xFF00)     <<  8) | \
-                               (((n) & 0xFF0000)   >>  8) | \
-                               (((n) & 0xFF000000) >> 24))
-#define LXW_UINT16_NETWORK(n) ((((n) & 0x00FF) << 8) | (((n) & 0xFF00) >> 8))
-#define LXW_UINT32_HOST(n)    (n)
-#else
-#define LXW_UINT32_NETWORK(n) (n)
-#define LXW_UINT16_NETWORK(n) (n)
-#define LXW_UINT32_HOST(n)    ((((n) & 0xFF)       << 24) | \
-                               (((n) & 0xFF00)     <<  8) | \
-                               (((n) & 0xFF0000)   >>  8) | \
-                               (((n) & 0xFF000000) >> 24))
-#endif
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-/* Compilers that have a native snprintf() can use it directly. */
-#ifdef _MSC_VER
-#define LXW_HAS_SNPRINTF
-#endif
-
-#ifdef LXW_HAS_SNPRINTF
-#define lxw_snprintf snprintf
-#else
-#define lxw_snprintf __builtin_snprintf
-#endif
-
-/* Define a snprintf for MSVC 2010. */
-#if defined(_MSC_VER) && _MSC_VER < 1900
-
-#include <stdarg.h>
-#define snprintf msvc2010_snprintf
-#define vsnprintf msvc2010_vsnprintf
-
-__inline int
-msvc2010_vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
-    int count = -1;
-
-    if (size != 0)
-        count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
-    if (count == -1)
-        count = _vscprintf(format, ap);
-
-    return count;
-}
-
-__inline int
-msvc2010_snprintf(char *str, size_t size, const char *format, ...)
-{
-    int count;
-    va_list ap;
-
-    va_start(ap, format);
-    count = msvc2010_vsnprintf(str, size, format, ap);
-    va_end(ap);
-
-    return count;
-}
-
-#endif
-
-/* Safer strcpy for fixed width char arrays. */
-#define lxw_strcpy(dest, src) \
-    lxw_snprintf(dest, sizeof(dest), "%s", src)
-
-/* Define the queue.h structs for the formats list. */
-STAILQ_HEAD(lxw_formats, lxw_format);
-
-/* Define the queue.h structs for the generic data structs. */
-STAILQ_HEAD(lxw_tuples, lxw_tuple);
-STAILQ_HEAD(lxw_custom_properties, lxw_custom_property);
-
-typedef struct lxw_tuple {
-    char *key;
-    char *value;
-
-    STAILQ_ENTRY (lxw_tuple) list_pointers;
-} lxw_tuple;
-
-/* Define custom property used in workbook.c and custom.c. */
-typedef struct lxw_custom_property {
-
-    enum lxw_custom_property_types type;
-    char *name;
-
-    union {
-        char *string;
-        double number;
-        int32_t integer;
-        uint8_t boolean;
-        lxw_datetime datetime;
-    } u;
-
-    STAILQ_ENTRY (lxw_custom_property) list_pointers;
-
-} lxw_custom_property;
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_COMMON_H__ */

+ 0 - 74
library/include/xlsxwriter/content_types.h

@@ -1,74 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * content_types - A libxlsxwriter library for creating Excel XLSX
- *                 content_types files.
- *
- */
-#ifndef __LXW_CONTENT_TYPES_H__
-#define __LXW_CONTENT_TYPES_H__
-
-#include <stdint.h>
-#include <string.h>
-
-#include "common.h"
-
-#define LXW_APP_PACKAGE  "application/vnd.openxmlformats-package."
-#define LXW_APP_DOCUMENT "application/vnd.openxmlformats-officedocument."
-
-/*
- * Struct to represent a content_types.
- */
-typedef struct lxw_content_types {
-
-    FILE *file;
-
-    struct lxw_tuples *default_types;
-    struct lxw_tuples *overrides;
-
-} lxw_content_types;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_content_types *lxw_content_types_new();
-void lxw_content_types_free(lxw_content_types *content_types);
-void lxw_content_types_assemble_xml_file(lxw_content_types *content_types);
-void lxw_ct_add_default(lxw_content_types *content_types, const char *key,
-                        const char *value);
-void lxw_ct_add_override(lxw_content_types *content_types, const char *key,
-                         const char *value);
-void lxw_ct_add_worksheet_name(lxw_content_types *content_types,
-                               const char *name);
-void lxw_ct_add_chart_name(lxw_content_types *content_types,
-                           const char *name);
-void lxw_ct_add_drawing_name(lxw_content_types *content_types,
-                             const char *name);
-void lxw_ct_add_shared_strings(lxw_content_types *content_types);
-void lxw_ct_add_calc_chain(lxw_content_types *content_types);
-void lxw_ct_add_custom_properties(lxw_content_types *content_types);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _content_types_xml_declaration(lxw_content_types *self);
-STATIC void _write_default(lxw_content_types *self, const char *ext,
-                           const char *type);
-STATIC void _write_override(lxw_content_types *self, const char *part_name,
-                            const char *type);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_CONTENT_TYPES_H__ */

+ 0 - 51
library/include/xlsxwriter/core.h

@@ -1,51 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * core - A libxlsxwriter library for creating Excel XLSX core files.
- *
- */
-#ifndef __LXW_CORE_H__
-#define __LXW_CORE_H__
-
-#include <stdint.h>
-
-#include "workbook.h"
-#include "common.h"
-
-/*
- * Struct to represent a core.
- */
-typedef struct lxw_core {
-
-    FILE *file;
-    lxw_doc_properties *properties;
-
-} lxw_core;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_core *lxw_core_new();
-void lxw_core_free(lxw_core *core);
-void lxw_core_assemble_xml_file(lxw_core *self);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _core_xml_declaration(lxw_core *self);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_CORE_H__ */

+ 0 - 52
library/include/xlsxwriter/custom.h

@@ -1,52 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * custom - A libxlsxwriter library for creating Excel custom property files.
- *
- */
-#ifndef __LXW_CUSTOM_H__
-#define __LXW_CUSTOM_H__
-
-#include <stdint.h>
-
-#include "common.h"
-
-/*
- * Struct to represent a custom property file object.
- */
-typedef struct lxw_custom {
-
-    FILE *file;
-
-    struct lxw_custom_properties *custom_properties;
-    uint32_t pid;
-
-} lxw_custom;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_custom *lxw_custom_new();
-void lxw_custom_free(lxw_custom *custom);
-void lxw_custom_assemble_xml_file(lxw_custom *self);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _custom_xml_declaration(lxw_custom *self);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_CUSTOM_H__ */

+ 0 - 111
library/include/xlsxwriter/drawing.h

@@ -1,111 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * drawing - A libxlsxwriter library for creating Excel XLSX drawing files.
- *
- */
-#ifndef __LXW_DRAWING_H__
-#define __LXW_DRAWING_H__
-
-#include <stdint.h>
-
-#include "common.h"
-
-STAILQ_HEAD(lxw_drawing_objects, lxw_drawing_object);
-
-enum lxw_drawing_types {
-    LXW_DRAWING_NONE = 0,
-    LXW_DRAWING_IMAGE,
-    LXW_DRAWING_CHART,
-    LXW_DRAWING_SHAPE
-};
-
-enum lxw_anchor_types {
-    LXW_ANCHOR_TYPE_NONE = 0,
-    LXW_ANCHOR_TYPE_IMAGE,
-    LXW_ANCHOR_TYPE_CHART
-};
-
-enum lxw_anchor_edit_types {
-    LXW_ANCHOR_EDIT_AS_NONE = 0,
-    LXW_ANCHOR_EDIT_AS_RELATIVE,
-    LXW_ANCHOR_EDIT_AS_ONE_CELL,
-    LXW_ANCHOR_EDIT_AS_ABSOLUTE
-};
-
-enum image_types {
-    LXW_IMAGE_UNKNOWN = 0,
-    LXW_IMAGE_PNG,
-    LXW_IMAGE_JPEG,
-    LXW_IMAGE_BMP
-};
-
-/* Coordinates used in a drawing object. */
-typedef struct lxw_drawing_coords {
-    uint32_t col;
-    uint32_t row;
-    double col_offset;
-    double row_offset;
-} lxw_drawing_coords;
-
-/* Object to represent the properties of a drawing. */
-typedef struct lxw_drawing_object {
-    uint8_t anchor_type;
-    uint8_t edit_as;
-    struct lxw_drawing_coords from;
-    struct lxw_drawing_coords to;
-    uint32_t col_absolute;
-    uint32_t row_absolute;
-    uint32_t width;
-    uint32_t height;
-    uint8_t shape;
-    char *description;
-    char *url;
-    char *tip;
-
-    STAILQ_ENTRY (lxw_drawing_object) list_pointers;
-
-} lxw_drawing_object;
-
-/*
- * Struct to represent a collection of drawings.
- */
-typedef struct lxw_drawing {
-
-    FILE *file;
-
-    uint8_t embedded;
-
-    struct lxw_drawing_objects *drawing_objects;
-
-} lxw_drawing;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_drawing *lxw_drawing_new();
-void lxw_drawing_free(lxw_drawing *drawing);
-void lxw_drawing_assemble_xml_file(lxw_drawing *self);
-void lxw_free_drawing_object(struct lxw_drawing_object *drawing_object);
-void lxw_add_drawing_object(lxw_drawing *drawing,
-                            lxw_drawing_object *drawing_object);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _drawing_xml_declaration(lxw_drawing *self);
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_DRAWING_H__ */

+ 0 - 1214
library/include/xlsxwriter/format.h

@@ -1,1214 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- */
-
-/**
- * @page format_page The Format object
- *
- * The Format object represents an the formatting properties that can be
- * applied to a cell including: fonts, colors, patterns,
- * borders, alignment and number formatting.
- *
- * See @ref format.h for full details of the functionality.
- *
- * @file format.h
- *
- * @brief Functions and properties for adding formatting to cells in Excel.
- *
- * This section describes the functions and properties that are available for
- * formatting cells in Excel.
- *
- * The properties of a cell that can be formatted include: fonts, colors,
- * patterns, borders, alignment and number formatting.
- *
- * @image html formats_intro.png
- *
- * Formats in `libxlsxwriter` are accessed via the lxw_format
- * struct. Throughout this document these will be referred to simply as
- * *Formats*.
- *
- * Formats are created by calling the workbook_add_format() method as
- * follows:
- *
- * @code
- *     lxw_format *format = workbook_add_format(workbook);
- * @endcode
- *
- * The members of the lxw_format struct aren't modified directly. Instead the
- * format properties are set by calling the functions shown in this section.
- * For example:
- *
- * @code
- *    // Create the Format.
- *    lxw_format *format = workbook_add_format(workbook);
- *
- *    // Set some of the format properties.
- *    format_set_bold(format);
- *    format_set_font_color(format, LXW_COLOR_RED);
- *
- *    // Use the format to change the text format in a cell.
- *    worksheet_write_string(worksheet, 0, 0, "Hello", format);
- *
- * @endcode
- *
- * The full range of formatting options that can be applied using
- * `libxlsxwriter` are shown below.
- *
- */
-#ifndef __LXW_FORMAT_H__
-#define __LXW_FORMAT_H__
-
-#include <stdint.h>
-#include <string.h>
-#include "hash_table.h"
-
-#include "common.h"
-
-/**
- * @brief The type for RGB colors in libxlsxwriter.
- *
- * The type for RGB colors in libxlsxwriter. The valid range is `0x000000`
- * (black) to `0xFFFFFF` (white). See @ref working_with_colors.
- */
-typedef int32_t lxw_color_t;
-
-#define LXW_FORMAT_FIELD_LEN            128
-#define LXW_DEFAULT_FONT_NAME           "Calibri"
-#define LXW_DEFAULT_FONT_FAMILY         2
-#define LXW_DEFAULT_FONT_THEME          1
-#define LXW_PROPERTY_UNSET              -1
-#define LXW_COLOR_UNSET                 -1
-#define LXW_COLOR_MASK                  0xFFFFFF
-#define LXW_MIN_FONT_SIZE               1.0
-#define LXW_MAX_FONT_SIZE               409.0
-
-#define LXW_FORMAT_FIELD_COPY(dst, src)             \
-    do{                                             \
-        strncpy(dst, src, LXW_FORMAT_FIELD_LEN -1); \
-        dst[LXW_FORMAT_FIELD_LEN - 1] = '\0';       \
-    } while (0)
-
-/** Format underline values for format_set_underline(). */
-enum lxw_format_underlines {
-    /** Single underline */
-    LXW_UNDERLINE_SINGLE = 1,
-
-    /** Double underline */
-    LXW_UNDERLINE_DOUBLE,
-
-    /** Single accounting underline */
-    LXW_UNDERLINE_SINGLE_ACCOUNTING,
-
-    /** Double accounting underline */
-    LXW_UNDERLINE_DOUBLE_ACCOUNTING
-};
-
-/** Superscript and subscript values for format_set_font_script(). */
-enum lxw_format_scripts {
-
-    /** Superscript font */
-    LXW_FONT_SUPERSCRIPT = 1,
-
-    /** Subscript font */
-    LXW_FONT_SUBSCRIPT
-};
-
-/** Alignment values for format_set_align(). */
-enum lxw_format_alignments {
-    /** No alignment. Cell will use Excel's default for the data type */
-    LXW_ALIGN_NONE = 0,
-
-    /** Left horizontal alignment */
-    LXW_ALIGN_LEFT,
-
-    /** Center horizontal alignment */
-    LXW_ALIGN_CENTER,
-
-    /** Right horizontal alignment */
-    LXW_ALIGN_RIGHT,
-
-    /** Cell fill horizontal alignment */
-    LXW_ALIGN_FILL,
-
-    /** Justify horizontal alignment */
-    LXW_ALIGN_JUSTIFY,
-
-    /** Center Across horizontal alignment */
-    LXW_ALIGN_CENTER_ACROSS,
-
-    /** Left horizontal alignment */
-    LXW_ALIGN_DISTRIBUTED,
-
-    /** Top vertical alignment */
-    LXW_ALIGN_VERTICAL_TOP,
-
-    /** Bottom vertical alignment */
-    LXW_ALIGN_VERTICAL_BOTTOM,
-
-    /** Center vertical alignment */
-    LXW_ALIGN_VERTICAL_CENTER,
-
-    /** Justify vertical alignment */
-    LXW_ALIGN_VERTICAL_JUSTIFY,
-
-    /** Distributed vertical alignment */
-    LXW_ALIGN_VERTICAL_DISTRIBUTED
-};
-
-enum lxw_format_diagonal_types {
-    LXW_DIAGONAL_BORDER_UP = 1,
-    LXW_DIAGONAL_BORDER_DOWN,
-    LXW_DIAGONAL_BORDER_UP_DOWN
-};
-
-/** Predefined values for common colors. */
-enum lxw_defined_colors {
-    /** Black */
-    LXW_COLOR_BLACK = 0x1000000,
-
-    /** Blue */
-    LXW_COLOR_BLUE = 0x0000FF,
-
-    /** Brown */
-    LXW_COLOR_BROWN = 0x800000,
-
-    /** Cyan */
-    LXW_COLOR_CYAN = 0x00FFFF,
-
-    /** Gray */
-    LXW_COLOR_GRAY = 0x808080,
-
-    /** Green */
-    LXW_COLOR_GREEN = 0x008000,
-
-    /** Lime */
-    LXW_COLOR_LIME = 0x00FF00,
-
-    /** Magenta */
-    LXW_COLOR_MAGENTA = 0xFF00FF,
-
-    /** Navy */
-    LXW_COLOR_NAVY = 0x000080,
-
-    /** Orange */
-    LXW_COLOR_ORANGE = 0xFF6600,
-
-    /** Pink */
-    LXW_COLOR_PINK = 0xFF00FF,
-
-    /** Purple */
-    LXW_COLOR_PURPLE = 0x800080,
-
-    /** Red */
-    LXW_COLOR_RED = 0xFF0000,
-
-    /** Silver */
-    LXW_COLOR_SILVER = 0xC0C0C0,
-
-    /** White */
-    LXW_COLOR_WHITE = 0xFFFFFF,
-
-    /** Yellow */
-    LXW_COLOR_YELLOW = 0xFFFF00
-};
-
-/** Pattern value for use with format_set_pattern(). */
-enum lxw_format_patterns {
-    /** Empty pattern */
-    LXW_PATTERN_NONE = 0,
-
-    /** Solid pattern */
-    LXW_PATTERN_SOLID,
-
-    /** Medium gray pattern */
-    LXW_PATTERN_MEDIUM_GRAY,
-
-    /** Dark gray pattern */
-    LXW_PATTERN_DARK_GRAY,
-
-    /** Light gray pattern */
-    LXW_PATTERN_LIGHT_GRAY,
-
-    /** Dark horizontal line pattern */
-    LXW_PATTERN_DARK_HORIZONTAL,
-
-    /** Dark vertical line pattern */
-    LXW_PATTERN_DARK_VERTICAL,
-
-    /** Dark diagonal stripe pattern */
-    LXW_PATTERN_DARK_DOWN,
-
-    /** Reverse dark diagonal stripe pattern */
-    LXW_PATTERN_DARK_UP,
-
-    /** Dark grid pattern */
-    LXW_PATTERN_DARK_GRID,
-
-    /** Dark trellis pattern */
-    LXW_PATTERN_DARK_TRELLIS,
-
-    /** Light horizontal Line pattern */
-    LXW_PATTERN_LIGHT_HORIZONTAL,
-
-    /** Light vertical line pattern */
-    LXW_PATTERN_LIGHT_VERTICAL,
-
-    /** Light diagonal stripe pattern */
-    LXW_PATTERN_LIGHT_DOWN,
-
-    /** Reverse light diagonal stripe pattern */
-    LXW_PATTERN_LIGHT_UP,
-
-    /** Light grid pattern */
-    LXW_PATTERN_LIGHT_GRID,
-
-    /** Light trellis pattern */
-    LXW_PATTERN_LIGHT_TRELLIS,
-
-    /** 12.5% gray pattern */
-    LXW_PATTERN_GRAY_125,
-
-    /** 6.25% gray pattern */
-    LXW_PATTERN_GRAY_0625
-};
-
-/** Cell border styles for use with format_set_border(). */
-enum lxw_format_borders {
-    /** No border */
-    LXW_BORDER_NONE,
-
-    /** Thin border style */
-    LXW_BORDER_THIN,
-
-    /** Medium border style */
-    LXW_BORDER_MEDIUM,
-
-    /** Dashed border style */
-    LXW_BORDER_DASHED,
-
-    /** Dotted border style */
-    LXW_BORDER_DOTTED,
-
-    /** Thick border style */
-    LXW_BORDER_THICK,
-
-    /** Double border style */
-    LXW_BORDER_DOUBLE,
-
-    /** Hair border style */
-    LXW_BORDER_HAIR,
-
-    /** Medium dashed border style */
-    LXW_BORDER_MEDIUM_DASHED,
-
-    /** Dash-dot border style */
-    LXW_BORDER_DASH_DOT,
-
-    /** Medium dash-dot border style */
-    LXW_BORDER_MEDIUM_DASH_DOT,
-
-    /** Dash-dot-dot border style */
-    LXW_BORDER_DASH_DOT_DOT,
-
-    /** Medium dash-dot-dot border style */
-    LXW_BORDER_MEDIUM_DASH_DOT_DOT,
-
-    /** Slant dash-dot border style */
-    LXW_BORDER_SLANT_DASH_DOT
-};
-
-/**
- * @brief Struct to represent the formatting properties of an Excel format.
- *
- * Formats in `libxlsxwriter` are accessed via this struct.
- *
- * The members of the lxw_format struct aren't modified directly. Instead the
- * format properties are set by calling the functions shown in format.h.
- *
- * For example:
- *
- * @code
- *    // Create the Format.
- *    lxw_format *format = workbook_add_format(workbook);
- *
- *    // Set some of the format properties.
- *    format_set_bold(format);
- *    format_set_font_color(format, LXW_COLOR_RED);
- *
- *    // Use the format to change the text format in a cell.
- *    worksheet_write_string(worksheet, 0, 0, "Hello", format);
- *
- * @endcode
- *
- */
-typedef struct lxw_format {
-
-    FILE *file;
-
-    lxw_hash_table *xf_format_indices;
-    uint16_t *num_xf_formats;
-
-    int32_t xf_index;
-    int32_t dxf_index;
-
-    char num_format[LXW_FORMAT_FIELD_LEN];
-    char font_name[LXW_FORMAT_FIELD_LEN];
-    char font_scheme[LXW_FORMAT_FIELD_LEN];
-    uint16_t num_format_index;
-    uint16_t font_index;
-    uint8_t has_font;
-    uint8_t has_dxf_font;
-    double font_size;
-    uint8_t bold;
-    uint8_t italic;
-    lxw_color_t font_color;
-    uint8_t underline;
-    uint8_t font_strikeout;
-    uint8_t font_outline;
-    uint8_t font_shadow;
-    uint8_t font_script;
-    uint8_t font_family;
-    uint8_t font_charset;
-    uint8_t font_condense;
-    uint8_t font_extend;
-    uint8_t theme;
-    uint8_t hyperlink;
-
-    uint8_t hidden;
-    uint8_t locked;
-
-    uint8_t text_h_align;
-    uint8_t text_wrap;
-    uint8_t text_v_align;
-    uint8_t text_justlast;
-    int16_t rotation;
-
-    lxw_color_t fg_color;
-    lxw_color_t bg_color;
-    uint8_t pattern;
-    uint8_t has_fill;
-    uint8_t has_dxf_fill;
-    int32_t fill_index;
-    int32_t fill_count;
-
-    int32_t border_index;
-    uint8_t has_border;
-    uint8_t has_dxf_border;
-    int32_t border_count;
-
-    uint8_t bottom;
-    uint8_t diag_border;
-    uint8_t diag_type;
-    uint8_t left;
-    uint8_t right;
-    uint8_t top;
-    lxw_color_t bottom_color;
-    lxw_color_t diag_color;
-    lxw_color_t left_color;
-    lxw_color_t right_color;
-    lxw_color_t top_color;
-
-    uint8_t indent;
-    uint8_t shrink;
-    uint8_t merge_range;
-    uint8_t reading_order;
-    uint8_t just_distrib;
-    uint8_t color_indexed;
-    uint8_t font_only;
-
-    STAILQ_ENTRY (lxw_format) list_pointers;
-} lxw_format;
-
-/*
- * Struct to represent the font component of a format.
- */
-typedef struct lxw_font {
-
-    char font_name[LXW_FORMAT_FIELD_LEN];
-    double font_size;
-    uint8_t bold;
-    uint8_t italic;
-    uint8_t underline;
-    uint8_t font_strikeout;
-    uint8_t font_outline;
-    uint8_t font_shadow;
-    uint8_t font_script;
-    uint8_t font_family;
-    uint8_t font_charset;
-    uint8_t font_condense;
-    uint8_t font_extend;
-    lxw_color_t font_color;
-} lxw_font;
-
-/*
- * Struct to represent the border component of a format.
- */
-typedef struct lxw_border {
-
-    uint8_t bottom;
-    uint8_t diag_border;
-    uint8_t diag_type;
-    uint8_t left;
-    uint8_t right;
-    uint8_t top;
-
-    lxw_color_t bottom_color;
-    lxw_color_t diag_color;
-    lxw_color_t left_color;
-    lxw_color_t right_color;
-    lxw_color_t top_color;
-
-} lxw_border;
-
-/*
- * Struct to represent the fill component of a format.
- */
-typedef struct lxw_fill {
-
-    lxw_color_t fg_color;
-    lxw_color_t bg_color;
-    uint8_t pattern;
-
-} lxw_fill;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_format *lxw_format_new();
-void lxw_format_free(lxw_format *format);
-int32_t lxw_format_get_xf_index(lxw_format *format);
-lxw_font *lxw_format_get_font_key(lxw_format *format);
-lxw_border *lxw_format_get_border_key(lxw_format *format);
-lxw_fill *lxw_format_get_fill_key(lxw_format *format);
-
-lxw_color_t lxw_format_check_color(lxw_color_t color);
-
-/**
- * @brief Set the font used in the cell.
- *
- * @param format    Pointer to a Format instance.
- * @param font_name Cell font name.
- *
- * Specify the font used used in the cell format:
- *
- * @code
- *     format_set_font_name(format, "Avenir Black Oblique");
- * @endcode
- *
- * @image html format_set_font_name.png
- *
- * Excel can only display fonts that are installed on the system that it is
- * running on. Therefore it is generally best to use the fonts that come as
- * standard with Excel such as Calibri, Times New Roman and Courier New.
- *
- * The default font in Excel 2007, and later, is Calibri.
- */
-void format_set_font_name(lxw_format *format, const char *font_name);
-
-/**
- * @brief Set the size of the font used in the cell.
- *
- * @param format Pointer to a Format instance.
- * @param size   The cell font size.
- *
- * Set the font size of the cell format:
- *
- * @code
- *     format_set_font_size(format, 30);
- * @endcode
- *
- * @image html format_font_size.png
- *
- * Excel adjusts the height of a row to accommodate the largest font
- * size in the row. You can also explicitly specify the height of a
- * row using the worksheet_set_row() function.
- */
-void format_set_font_size(lxw_format *format, double size);
-
-/**
- * @brief Set the color of the font used in the cell.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell font color.
- *
- *
- * Set the font color:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_font_color(format, LXW_COLOR_RED);
- *
- *     worksheet_write_string(worksheet, 0, 0, "Wheelbarrow", format);
- * @endcode
- *
- * @image html format_font_color.png
- *
- * The color should be an RGB integer value, see @ref working_with_colors.
- *
- * @note
- * The format_set_font_color() method is used to set the font color in a
- * cell. To set the color of a cell background use the format_set_bg_color()
- * and format_set_pattern() methods.
- */
-void format_set_font_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Turn on bold for the format font.
- *
- * @param format Pointer to a Format instance.
- *
- * Set the bold property of the font:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_bold(format);
- *
- *     worksheet_write_string(worksheet, 0, 0, "Bold Text", format);
- * @endcode
- *
- * @image html format_font_bold.png
- */
-void format_set_bold(lxw_format *format);
-
-/**
- * @brief Turn on italic for the format font.
- *
- * @param format Pointer to a Format instance.
- *
- * Set the italic property of the font:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_italic(format);
- *
- *     worksheet_write_string(worksheet, 0, 0, "Italic Text", format);
- * @endcode
- *
- * @image html format_font_italic.png
- */
-void format_set_italic(lxw_format *format);
-
-/**
- * @brief Turn on underline for the format:
- *
- * @param format Pointer to a Format instance.
- * @param style Underline style.
- *
- * Set the underline property of the format:
- *
- * @code
- *     format_set_underline(format, LXW_UNDERLINE_SINGLE);
- * @endcode
- *
- * @image html format_font_underlined.png
- *
- * The available underline styles are:
- *
- * - #LXW_UNDERLINE_SINGLE
- * - #LXW_UNDERLINE_DOUBLE
- * - #LXW_UNDERLINE_SINGLE_ACCOUNTING
- * - #LXW_UNDERLINE_DOUBLE_ACCOUNTING
- *
- */
-void format_set_underline(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the strikeout property of the font.
- *
- * @param format Pointer to a Format instance.
- *
- * @image html format_font_strikeout.png
- *
- */
-void format_set_font_strikeout(lxw_format *format);
-
-/**
- * @brief Set the superscript/subscript property of the font.
- *
- * @param format Pointer to a Format instance.
- * @param style  Superscript or subscript style.
- *
- * Set the superscript o subscript property of the font.
- *
- * @image html format_font_script.png
- *
- * The available script styles are:
- *
- * - #LXW_FONT_SUPERSCRIPT
- * - #LXW_FONT_SUBSCRIPT
- */
-void format_set_font_script(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the number format for a cell.
- *
- * @param format      Pointer to a Format instance.
- * @param num_format The cell number format string.
- *
- * This method is used to define the numerical format of a number in
- * Excel. It controls whether a number is displayed as an integer, a
- * floating point number, a date, a currency value or some other user
- * defined format.
- *
- * The numerical format of a cell can be specified by using a format
- * string:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_num_format(format, "d mmm yyyy");
- * @endcode
- *
- * Format strings can control any aspect of number formatting allowed by Excel:
- *
- * @dontinclude format_num_format.c
- * @skipline set_num_format
- * @until 1209
- *
- * @image html format_set_num_format.png
- *
- * The number system used for dates is described in @ref working_with_dates.
- *
- * For more information on number formats in Excel refer to the
- * [Microsoft documentation on cell formats](http://office.microsoft.com/en-gb/assistance/HP051995001033.aspx).
- */
-void format_set_num_format(lxw_format *format, const char *num_format);
-
-/**
- * @brief Set the Excel built-in number format for a cell.
- *
- * @param format Pointer to a Format instance.
- * @param index  The built-in number format index for the cell.
- *
- * This function is similar to format_set_num_format() except that it takes an
- * index to a limited number of Excel's built-in number formats instead of a
- * user defined format string:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_num_format(format, 0x0F);     // d-mmm-yy
- * @endcode
- *
- * @note
- * Unless you need to specifically access one of Excel's built-in number
- * formats the format_set_num_format() function above is a better
- * solution. The format_set_num_format_index() function is mainly included for
- * backward compatibility and completeness.
- *
- * The Excel built-in number formats as shown in the table below:
- *
- *   | Index | Index | Format String                                        |
- *   | ----- | ----- | ---------------------------------------------------- |
- *   | 0     | 0x00  | `General`                                            |
- *   | 1     | 0x01  | `0`                                                  |
- *   | 2     | 0x02  | `0.00`                                               |
- *   | 3     | 0x03  | `#,##0`                                              |
- *   | 4     | 0x04  | `#,##0.00`                                           |
- *   | 5     | 0x05  | `($#,##0_);($#,##0)`                                 |
- *   | 6     | 0x06  | `($#,##0_);[Red]($#,##0)`                            |
- *   | 7     | 0x07  | `($#,##0.00_);($#,##0.00)`                           |
- *   | 8     | 0x08  | `($#,##0.00_);[Red]($#,##0.00)`                      |
- *   | 9     | 0x09  | `0%`                                                 |
- *   | 10    | 0x0a  | `0.00%`                                              |
- *   | 11    | 0x0b  | `0.00E+00`                                           |
- *   | 12    | 0x0c  | `# ?/?`                                              |
- *   | 13    | 0x0d  | `# ??/??`                                            |
- *   | 14    | 0x0e  | `m/d/yy`                                             |
- *   | 15    | 0x0f  | `d-mmm-yy`                                           |
- *   | 16    | 0x10  | `d-mmm`                                              |
- *   | 17    | 0x11  | `mmm-yy`                                             |
- *   | 18    | 0x12  | `h:mm AM/PM`                                         |
- *   | 19    | 0x13  | `h:mm:ss AM/PM`                                      |
- *   | 20    | 0x14  | `h:mm`                                               |
- *   | 21    | 0x15  | `h:mm:ss`                                            |
- *   | 22    | 0x16  | `m/d/yy h:mm`                                        |
- *   | ...   | ...   | ...                                                  |
- *   | 37    | 0x25  | `(#,##0_);(#,##0)`                                   |
- *   | 38    | 0x26  | `(#,##0_);[Red](#,##0)`                              |
- *   | 39    | 0x27  | `(#,##0.00_);(#,##0.00)`                             |
- *   | 40    | 0x28  | `(#,##0.00_);[Red](#,##0.00)`                        |
- *   | 41    | 0x29  | `_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)`            |
- *   | 42    | 0x2a  | `_($* #,##0_);_($* (#,##0);_($* "-"_);_(@_)`         |
- *   | 43    | 0x2b  | `_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)`    |
- *   | 44    | 0x2c  | `_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)` |
- *   | 45    | 0x2d  | `mm:ss`                                              |
- *   | 46    | 0x2e  | `[h]:mm:ss`                                          |
- *   | 47    | 0x2f  | `mm:ss.0`                                            |
- *   | 48    | 0x30  | `##0.0E+0`                                           |
- *   | 49    | 0x31  | `@`                                                  |
- *
- * @note
- *  -  Numeric formats 23 to 36 are not documented by Microsoft and may differ
- *     in international versions. The listed date and currency formats may also
- *     vary depending on system settings.
- *  - The dollar sign in the above format appears as the defined local currency
- *    symbol.
- *  - These formats can also be set via format_set_num_format().
- */
-void format_set_num_format_index(lxw_format *format, uint8_t index);
-
-/**
- * @brief Set the cell unlocked state.
- *
- * @param format Pointer to a Format instance.
- *
- * This property can be used to allow modification of a cell in a protected
- * worksheet. In Excel, cell locking is turned on by default for all
- * cells. However, it only has an effect if the worksheet has been protected
- * using the worksheet worksheet_protect() function:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_unlocked(format);
- *
- *     // Enable worksheet protection, without password or options.
- *     worksheet_protect(worksheet, NULL, NULL);
- *
- *     // This cell cannot be edited.
- *     worksheet_write_formula(worksheet, 0, 0, "=1+2", NULL);
- *
- *     // This cell can be edited.
- *     worksheet_write_formula(worksheet, 1, 0, "=1+2", format);
- * @endcode
- */
-void format_set_unlocked(lxw_format *format);
-
-/**
- * @brief Hide formulas in a cell.
- *
- * @param format Pointer to a Format instance.
- *
- * This property is used to hide a formula while still displaying its
- * result. This is generally used to hide complex calculations from end users
- * who are only interested in the result. It only has an effect if the
- * worksheet has been protected using the worksheet worksheet_protect()
- * function:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_hidden(format);
- *
- *     // Enable worksheet protection, without password or options.
- *     worksheet_protect(worksheet, NULL, NULL);
- *
- *     // The formula in this cell isn't visible.
- *     worksheet_write_formula(worksheet, 0, 0, "=1+2", format);
- * @endcode
- */
-void format_set_hidden(lxw_format *format);
-
-/**
- * @brief Set the alignment for data in the cell.
- *
- * @param format    Pointer to a Format instance.
- * @param alignment The horizontal and or vertical alignment direction.
- *
- * This method is used to set the horizontal and vertical text alignment within a
- * cell. The following are the available horizontal alignments:
- *
- * - #LXW_ALIGN_LEFT
- * - #LXW_ALIGN_CENTER
- * - #LXW_ALIGN_RIGHT
- * - #LXW_ALIGN_FILL
- * - #LXW_ALIGN_JUSTIFY
- * - #LXW_ALIGN_CENTER_ACROSS
- * - #LXW_ALIGN_DISTRIBUTED
- *
- * The following are the available vertical alignments:
- *
- * - #LXW_ALIGN_VERTICAL_TOP
- * - #LXW_ALIGN_VERTICAL_BOTTOM
- * - #LXW_ALIGN_VERTICAL_CENTER
- * - #LXW_ALIGN_VERTICAL_JUSTIFY
- * - #LXW_ALIGN_VERTICAL_DISTRIBUTED
- *
- * As in Excel, vertical and horizontal alignments can be combined:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *
- *     format_set_align(format, LXW_ALIGN_CENTER);
- *     format_set_align(format, LXW_ALIGN_VERTICAL_CENTER);
- *
- *     worksheet_set_row(0, 30);
- *     worksheet_write_string(worksheet, 0, 0, "Some Text", format);
- * @endcode
- *
- * @image html format_font_align.png
- *
- * Text can be aligned across two or more adjacent cells using the
- * center_across property. However, for genuine merged cells it is better to
- * use the worksheet_merge_range() worksheet method.
- *
- * The vertical justify option can be used to provide automatic text wrapping
- * in a cell. The height of the cell will be adjusted to accommodate the
- * wrapped text. To specify where the text wraps use the
- * format_set_text_wrap() method.
- */
-void format_set_align(lxw_format *format, uint8_t alignment);
-
-/**
- * @brief Wrap text in a cell.
- *
- * Turn text wrapping on for text in a cell.
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_text_wrap(format);
- *
- *     worksheet_write_string(worksheet, 0, 0, "Some long text to wrap in a cell", format);
- * @endcode
- *
- * If you wish to control where the text is wrapped you can add newline characters
- * to the string:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_text_wrap(format);
- *
- *     worksheet_write_string(worksheet, 0, 0, "It's\na bum\nwrap", format);
- * @endcode
- *
- * @image html format_font_text_wrap.png
- *
- * Excel will adjust the height of the row to accommodate the wrapped text. A
- * similar effect can be obtained without newlines using the
- * format_set_align() function with #LXW_ALIGN_VERTICAL_JUSTIFY.
- */
-void format_set_text_wrap(lxw_format *format);
-
-/**
- * @brief Set the rotation of the text in a cell.
- *
- * @param format Pointer to a Format instance.
- * @param angle  Rotation angle in the range -90 to 90 and 270.
- *
- * Set the rotation of the text in a cell. The rotation can be any angle in the
- * range -90 to 90 degrees:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_rotation(format, 30);
- *
- *     worksheet_write_string(worksheet, 0, 0, "This text is rotated", format);
- * @endcode
- *
- * @image html format_font_text_rotated.png
- *
- * The angle 270 is also supported. This indicates text where the letters run from
- * top to bottom.
- */
-void format_set_rotation(lxw_format *format, int16_t angle);
-
-/**
- * @brief Set the cell text indentation level.
- *
- * @param format Pointer to a Format instance.
- * @param level  Indentation level.
- *
- * This method can be used to indent text in a cell. The argument, which should be
- * an integer, is taken as the level of indentation:
- *
- * @code
- *     format1 = workbook_add_format(workbook);
- *     format2 = workbook_add_format(workbook);
- *
- *     format_set_indent(format1, 1);
- *     format_set_indent(format2, 2);
- *
- *     worksheet_write_string(worksheet, 0, 0, "This text is indented 1 level",  format1);
- *     worksheet_write_string(worksheet, 1, 0, "This text is indented 2 levels", format2);
- * @endcode
- *
- * @image html text_indent.png
- *
- * @note
- * Indentation is a horizontal alignment property. It will override any other
- * horizontal properties but it can be used in conjunction with vertical
- * properties.
- */
-void format_set_indent(lxw_format *format, uint8_t level);
-
-/**
- * @brief Turn on the text "shrink to fit" for a cell.
- *
- * @param format Pointer to a Format instance.
- *
- * This method can be used to shrink text so that it fits in a cell:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *     format_set_shrink(format);
- *
- *     worksheet_write_string(worksheet, 0, 0, "Honey, I shrunk the text!", format);
- * @endcode
- */
-void format_set_shrink(lxw_format *format);
-
-/**
- * @brief Set the background fill pattern for a cell
- *
- * @param format Pointer to a Format instance.
- * @param index  Pattern index.
- *
- * Set the background pattern for a cell.
- *
- * The most common pattern is a solid fill of the background color:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *
- *     format_set_pattern (format, LXW_PATTERN_SOLID);
- *     format_set_bg_color(format, LXW_COLOR_YELLOW);
- * @endcode
- *
- * The available fill patterns are:
- *
- *    Fill Type                     | Define
- *    ----------------------------- | -----------------------------
- *    Solid                         | #LXW_PATTERN_SOLID
- *    Medium gray                   | #LXW_PATTERN_MEDIUM_GRAY
- *    Dark gray                     | #LXW_PATTERN_DARK_GRAY
- *    Light gray                    | #LXW_PATTERN_LIGHT_GRAY
- *    Dark horizontal line          | #LXW_PATTERN_DARK_HORIZONTAL
- *    Dark vertical line            | #LXW_PATTERN_DARK_VERTICAL
- *    Dark diagonal stripe          | #LXW_PATTERN_DARK_DOWN
- *    Reverse dark diagonal stripe  | #LXW_PATTERN_DARK_UP
- *    Dark grid                     | #LXW_PATTERN_DARK_GRID
- *    Dark trellis                  | #LXW_PATTERN_DARK_TRELLIS
- *    Light horizontal line         | #LXW_PATTERN_LIGHT_HORIZONTAL
- *    Light vertical line           | #LXW_PATTERN_LIGHT_VERTICAL
- *    Light diagonal stripe         | #LXW_PATTERN_LIGHT_DOWN
- *    Reverse light diagonal stripe | #LXW_PATTERN_LIGHT_UP
- *    Light grid                    | #LXW_PATTERN_LIGHT_GRID
- *    Light trellis                 | #LXW_PATTERN_LIGHT_TRELLIS
- *    12.5% gray                    | #LXW_PATTERN_GRAY_125
- *    6.25% gray                    | #LXW_PATTERN_GRAY_0625
- *
- */
-void format_set_pattern(lxw_format *format, uint8_t index);
-
-/**
- * @brief Set the pattern background color for a cell.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell pattern background color.
- *
- * The format_set_bg_color() method can be used to set the background color of
- * a pattern. Patterns are defined via the format_set_pattern() method. If a
- * pattern hasn't been defined then a solid fill pattern is used as the
- * default.
- *
- * Here is an example of how to set up a solid fill in a cell:
- *
- * @code
- *     format = workbook_add_format(workbook);
- *
- *     format_set_pattern (format, LXW_PATTERN_SOLID);
- *     format_set_bg_color(format, LXW_COLOR_GREEN);
- *
- *     worksheet_write_string(worksheet, 0, 0, "Ray", format);
- * @endcode
- *
- * @image html formats_set_bg_color.png
- *
- * The color should be an RGB integer value, see @ref working_with_colors.
- *
- */
-void format_set_bg_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Set the pattern foreground color for a cell.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell pattern foreground  color.
- *
- * The format_set_fg_color() method can be used to set the foreground color of
- * a pattern.
- *
- * The color should be an RGB integer value, see @ref working_with_colors.
- *
- */
-void format_set_fg_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Set the cell border style.
- *
- * @param format Pointer to a Format instance.
- * @param style  Border style index.
- *
- * Set the cell border style:
- *
- * @code
- *     format_set_border(format, LXW_BORDER_THIN);
- * @endcode
- *
- * Individual border elements can be configured using the following functions with
- * the same parameters:
- *
- * - format_set_bottom()
- * - format_set_top()
- * - format_set_left()
- * - format_set_right()
- *
- * A cell border is comprised of a border on the bottom, top, left and right.
- * These can be set to the same value using format_set_border() or
- * individually using the relevant method calls shown above.
- *
- * The following border styles are available:
- *
- * - #LXW_BORDER_THIN
- * - #LXW_BORDER_MEDIUM
- * - #LXW_BORDER_DASHED
- * - #LXW_BORDER_DOTTED
- * - #LXW_BORDER_THICK
- * - #LXW_BORDER_DOUBLE
- * - #LXW_BORDER_HAIR
- * - #LXW_BORDER_MEDIUM_DASHED
- * - #LXW_BORDER_DASH_DOT
- * - #LXW_BORDER_MEDIUM_DASH_DOT
- * - #LXW_BORDER_DASH_DOT_DOT
- * - #LXW_BORDER_MEDIUM_DASH_DOT_DOT
- * - #LXW_BORDER_SLANT_DASH_DOT
- *
- *  The most commonly used style is the `thin` style.
- */
-void format_set_border(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the cell bottom border style.
- *
- * @param format Pointer to a Format instance.
- * @param style  Border style index.
- *
- * Set the cell bottom border style. See format_set_border() for details on the
- * border styles.
- */
-void format_set_bottom(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the cell top border style.
- *
- * @param format Pointer to a Format instance.
- * @param style  Border style index.
- *
- * Set the cell top border style. See format_set_border() for details on the border
- * styles.
- */
-void format_set_top(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the cell left border style.
- *
- * @param format Pointer to a Format instance.
- * @param style  Border style index.
- *
- * Set the cell left border style. See format_set_border() for details on the
- * border styles.
- */
-void format_set_left(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the cell right border style.
- *
- * @param format Pointer to a Format instance.
- * @param style  Border style index.
- *
- * Set the cell right border style. See format_set_border() for details on the
- * border styles.
- */
-void format_set_right(lxw_format *format, uint8_t style);
-
-/**
- * @brief Set the color of the cell border.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell border color.
- *
- * Individual border elements can be configured using the following methods with
- * the same parameters:
- *
- * - format_set_bottom_color()
- * - format_set_top_color()
- * - format_set_left_color()
- * - format_set_right_color()
- *
- * Set the color of the cell borders. A cell border is comprised of a border
- * on the bottom, top, left and right. These can be set to the same color
- * using format_set_border_color() or individually using the relevant method
- * calls shown above.
- *
- * The color should be an RGB integer value, see @ref working_with_colors.
- */
-void format_set_border_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Set the color of the bottom cell border.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell border color.
- *
- * See format_set_border_color() for details on the border colors.
- */
-void format_set_bottom_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Set the color of the top cell border.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell border color.
- *
- * See format_set_border_color() for details on the border colors.
- */
-void format_set_top_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Set the color of the left cell border.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell border color.
- *
- * See format_set_border_color() for details on the border colors.
- */
-void format_set_left_color(lxw_format *format, lxw_color_t color);
-
-/**
- * @brief Set the color of the right cell border.
- *
- * @param format Pointer to a Format instance.
- * @param color  The cell border color.
- *
- * See format_set_border_color() for details on the border colors.
- */
-void format_set_right_color(lxw_format *format, lxw_color_t color);
-
-void format_set_diag_type(lxw_format *format, uint8_t value);
-void format_set_diag_color(lxw_format *format, lxw_color_t color);
-void format_set_diag_border(lxw_format *format, uint8_t value);
-void format_set_font_outline(lxw_format *format);
-void format_set_font_shadow(lxw_format *format);
-void format_set_font_family(lxw_format *format, uint8_t value);
-void format_set_font_charset(lxw_format *format, uint8_t value);
-void format_set_font_scheme(lxw_format *format, const char *font_scheme);
-void format_set_font_condense(lxw_format *format);
-void format_set_font_extend(lxw_format *format);
-void format_set_reading_order(lxw_format *format, uint8_t value);
-void format_set_theme(lxw_format *format, uint8_t value);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_FORMAT_H__ */

+ 0 - 76
library/include/xlsxwriter/hash_table.h

@@ -1,76 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * hash_table - Hash table functions for libxlsxwriter.
- *
- */
-
-#ifndef __LXW_HASH_TABLE_H__
-#define __LXW_HASH_TABLE_H__
-
-#include "common.h"
-
-/* Macro to loop over hash table elements in insertion order. */
-#define LXW_FOREACH_ORDERED(elem, hash_table) \
-    STAILQ_FOREACH((elem), (hash_table)->order_list, lxw_hash_order_pointers)
-
-/* List declarations. */
-STAILQ_HEAD(lxw_hash_order_list, lxw_hash_element);
-SLIST_HEAD(lxw_hash_bucket_list, lxw_hash_element);
-
-/* LXW_HASH hash table struct. */
-typedef struct lxw_hash_table {
-    uint32_t num_buckets;
-    uint32_t used_buckets;
-    uint32_t unique_count;
-    uint8_t free_key;
-    uint8_t free_value;
-
-    struct lxw_hash_order_list *order_list;
-    struct lxw_hash_bucket_list **buckets;
-} lxw_hash_table;
-
-/*
- * LXW_HASH table element struct.
- *
- * The hash elements contain pointers to allow them to be stored in
- * lists in the the hash table buckets and also pointers to track the
- * insertion order in a separate list.
- */
-typedef struct lxw_hash_element {
-    void *key;
-    void *value;
-
-    STAILQ_ENTRY (lxw_hash_element) lxw_hash_order_pointers;
-    SLIST_ENTRY (lxw_hash_element) lxw_hash_list_pointers;
-} lxw_hash_element;
-
-
- /* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_hash_element *lxw_hash_key_exists(lxw_hash_table *lxw_hash, void *key,
-                                      size_t key_len);
-lxw_hash_element *lxw_insert_hash_element(lxw_hash_table *lxw_hash, void *key,
-                                          void *value, size_t key_len);
-lxw_hash_table *lxw_hash_new(uint32_t num_buckets, uint8_t free_key,
-                             uint8_t free_value);
-void lxw_hash_free(lxw_hash_table *lxw_hash);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-#endif
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_HASH_TABLE_H__ */

+ 0 - 85
library/include/xlsxwriter/packager.h

@@ -1,85 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * packager - A libxlsxwriter library for creating Excel XLSX packager files.
- *
- */
-#ifndef __LXW_PACKAGER_H__
-#define __LXW_PACKAGER_H__
-
-#include <stdint.h>
-
-#ifdef USE_SYSTEM_MINIZIP
-#include "minizip/zip.h"
-#else
-#include "third_party/zip.h"
-#endif
-
-#include "common.h"
-#include "workbook.h"
-#include "worksheet.h"
-#include "shared_strings.h"
-#include "app.h"
-#include "core.h"
-#include "custom.h"
-#include "theme.h"
-#include "styles.h"
-#include "format.h"
-#include "content_types.h"
-#include "relationships.h"
-
-#define LXW_ZIP_BUFFER_SIZE (16384)
-
-/* If zlib returns Z_ERRNO then errno is set and we can trap that. Otherwise
- * return a default libxlsxwriter error. */
-#define RETURN_ON_ZIP_ERROR(err, default_err)   \
-    if (err == Z_ERRNO)                         \
-        return LXW_ERROR_ZIP_FILE_OPERATION;    \
-    else                                        \
-        return default_err;
-
-/*
- * Struct to represent a packager.
- */
-typedef struct lxw_packager {
-
-    FILE *file;
-    lxw_workbook *workbook;
-
-    size_t buffer_size;
-    zipFile zipfile;
-    zip_fileinfo zipfile_info;
-    char *filename;
-    char *buffer;
-    char *tmpdir;
-
-    uint16_t chart_count;
-    uint16_t drawing_count;
-
-} lxw_packager;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_packager *lxw_packager_new(const char *filename, char *tmpdir);
-void lxw_packager_free(lxw_packager *packager);
-lxw_error lxw_create_package(lxw_packager *self);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_PACKAGER_H__ */

+ 0 - 77
library/include/xlsxwriter/relationships.h

@@ -1,77 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * relationships - A libxlsxwriter library for creating Excel XLSX
- *                 relationships files.
- *
- */
-#ifndef __LXW_RELATIONSHIPS_H__
-#define __LXW_RELATIONSHIPS_H__
-
-#include <stdint.h>
-
-#include "common.h"
-
-/* Define the queue.h STAILQ structs for the generic data structs. */
-STAILQ_HEAD(lxw_rel_tuples, lxw_rel_tuple);
-
-typedef struct lxw_rel_tuple {
-
-    char *type;
-    char *target;
-    char *target_mode;
-
-    STAILQ_ENTRY (lxw_rel_tuple) list_pointers;
-
-} lxw_rel_tuple;
-
-/*
- * Struct to represent a relationships.
- */
-typedef struct lxw_relationships {
-
-    FILE *file;
-
-    uint32_t rel_id;
-    struct lxw_rel_tuples *relationships;
-
-} lxw_relationships;
-
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_relationships *lxw_relationships_new();
-void lxw_free_relationships(lxw_relationships *relationships);
-void lxw_relationships_assemble_xml_file(lxw_relationships *self);
-
-void lxw_add_document_relationship(lxw_relationships *self, const char *type,
-                                   const char *target);
-void lxw_add_package_relationship(lxw_relationships *self, const char *type,
-                                  const char *target);
-void lxw_add_ms_package_relationship(lxw_relationships *self,
-                                     const char *type, const char *target);
-void lxw_add_worksheet_relationship(lxw_relationships *self, const char *type,
-                                    const char *target,
-                                    const char *target_mode);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _relationships_xml_declaration(lxw_relationships *self);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_RELATIONSHIPS_H__ */

+ 0 - 83
library/include/xlsxwriter/shared_strings.h

@@ -1,83 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * shared_strings - A libxlsxwriter library for creating Excel XLSX
- *                  sst files.
- *
- */
-#ifndef __LXW_SST_H__
-#define __LXW_SST_H__
-
-#include <string.h>
-#include <stdint.h>
-
-#include "common.h"
-
-/* Define a tree.h RB structure for storing shared strings. */
-RB_HEAD(sst_rb_tree, sst_element);
-
-/* Define a queue.h structure for storing shared strings in insertion order. */
-STAILQ_HEAD(sst_order_list, sst_element);
-
-/* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
- * warnings and to avoid portability issues with the _unused attribute. */
-#define LXW_RB_GENERATE_ELEMENT(name, type, field, cmp) \
-    RB_GENERATE_INSERT_COLOR(name, type, field, static) \
-    RB_GENERATE_INSERT(name, type, field, cmp, static)  \
-    /* Add unused struct to allow adding a semicolon */ \
-    struct lxw_rb_generate_element{int unused;}
-
-/*
- * Elements of the SST table. They contain pointers to allow them to
- * be stored in a RB tree and also pointers to track the insertion order
- * in a separate list.
- */
-struct sst_element {
-    uint32_t index;
-    char *string;
-
-    STAILQ_ENTRY (sst_element) sst_order_pointers;
-    RB_ENTRY (sst_element) sst_tree_pointers;
-};
-
-/*
- * Struct to represent a sst.
- */
-typedef struct lxw_sst {
-    FILE *file;
-
-    uint32_t string_count;
-    uint32_t unique_count;
-
-    struct sst_order_list *order_list;
-    struct sst_rb_tree *rb_tree;
-
-} lxw_sst;
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_sst *lxw_sst_new();
-void lxw_sst_free(lxw_sst *sst);
-struct sst_element *lxw_get_sst_index(lxw_sst *sst, const char *string);
-void lxw_sst_assemble_xml_file(lxw_sst *self);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _sst_xml_declaration(lxw_sst *self);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_SST_H__ */

+ 0 - 77
library/include/xlsxwriter/styles.h

@@ -1,77 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * styles - A libxlsxwriter library for creating Excel XLSX styles files.
- *
- */
-#ifndef __LXW_STYLES_H__
-#define __LXW_STYLES_H__
-
-#include <stdint.h>
-
-#include "format.h"
-
-/*
- * Struct to represent a styles.
- */
-typedef struct lxw_styles {
-
-    FILE *file;
-    uint32_t font_count;
-    uint32_t xf_count;
-    uint32_t dxf_count;
-    uint32_t num_format_count;
-    uint32_t border_count;
-    uint32_t fill_count;
-    struct lxw_formats *xf_formats;
-    struct lxw_formats *dxf_formats;
-
-} lxw_styles;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_styles *lxw_styles_new();
-void lxw_styles_free(lxw_styles *styles);
-void lxw_styles_assemble_xml_file(lxw_styles *self);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _styles_xml_declaration(lxw_styles *self);
-STATIC void _write_style_sheet(lxw_styles *self);
-STATIC void _write_font_size(lxw_styles *self, double font_size);
-STATIC void _write_font_color_theme(lxw_styles *self, uint8_t theme);
-STATIC void _write_font_name(lxw_styles *self, const char *font_name);
-STATIC void _write_font_family(lxw_styles *self, uint8_t font_family);
-STATIC void _write_font_scheme(lxw_styles *self, const char *font_scheme);
-STATIC void _write_font(lxw_styles *self, lxw_format *format);
-STATIC void _write_fonts(lxw_styles *self);
-STATIC void _write_default_fill(lxw_styles *self, const char *pattern);
-STATIC void _write_fills(lxw_styles *self);
-STATIC void _write_border(lxw_styles *self, lxw_format *format);
-STATIC void _write_borders(lxw_styles *self);
-STATIC void _write_style_xf(lxw_styles *self);
-STATIC void _write_cell_style_xfs(lxw_styles *self);
-STATIC void _write_xf(lxw_styles *self, lxw_format *format);
-STATIC void _write_cell_xfs(lxw_styles *self);
-STATIC void _write_cell_style(lxw_styles *self);
-STATIC void _write_cell_styles(lxw_styles *self);
-STATIC void _write_dxfs(lxw_styles *self);
-STATIC void _write_table_styles(lxw_styles *self);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_STYLES_H__ */

+ 0 - 47
library/include/xlsxwriter/theme.h

@@ -1,47 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * theme - A libxlsxwriter library for creating Excel XLSX theme files.
- *
- */
-#ifndef __LXW_THEME_H__
-#define __LXW_THEME_H__
-
-#include <stdint.h>
-
-#include "common.h"
-
-/*
- * Struct to represent a theme.
- */
-typedef struct lxw_theme {
-
-    FILE *file;
-} lxw_theme;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-lxw_theme *lxw_theme_new();
-void lxw_theme_free(lxw_theme *theme);
-void lxw_theme_xml_declaration(lxw_theme *self);
-void lxw_theme_assemble_xml_file(lxw_theme *self);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_THEME_H__ */

+ 0 - 214
library/include/xlsxwriter/third_party/ioapi.h

@@ -1,214 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         Changes
-
-    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
-    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
-               More if/def section may be needed to support other platforms
-    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
-                          (but you should use iowin32.c for windows instead)
-
-*/
-
-
-/* Pragma added by libxlsxwriter to avoid warnings with -pedantic -ansi. */
-#ifndef _WIN32
-#pragma GCC system_header
-#endif
-
-#ifndef _ZLIBIOAPI64_H
-#define _ZLIBIOAPI64_H
-
-#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
-
-  // Linux needs this to support file operation on files larger then 4+GB
-  // But might need better if/def to select just the platforms that needs them.
-
-        #ifndef __USE_FILE_OFFSET64
-                #define __USE_FILE_OFFSET64
-        #endif
-        #ifndef __USE_LARGEFILE64
-                #define __USE_LARGEFILE64
-        #endif
-        #ifndef _LARGEFILE64_SOURCE
-                #define _LARGEFILE64_SOURCE
-        #endif
-        #ifndef _FILE_OFFSET_BIT
-                #define _FILE_OFFSET_BIT 64
-        #endif
-
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "zlib.h"
-
-#if defined(USE_FILE32API)
-#define fopen64 fopen
-#define ftello64 ftell
-#define fseeko64 fseek
-#else
-#ifdef __FreeBSD__
-#define fopen64 fopen
-#define ftello64 ftello
-#define fseeko64 fseeko
-#endif
-#ifdef _MSC_VER
- #define fopen64 fopen
- #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
-  #define ftello64 _ftelli64
-  #define fseeko64 _fseeki64
- #else // old MSC
-  #define ftello64 ftell
-  #define fseeko64 fseek
- #endif
-#endif
-#endif
-
-/*
-#ifndef ZPOS64_T
-  #ifdef _WIN32
-                #define ZPOS64_T fpos_t
-  #else
-    #include <stdint.h>
-    #define ZPOS64_T uint64_t
-  #endif
-#endif
-*/
-
-#ifdef HAVE_MINIZIP64_CONF_H
-#include "mz64conf.h"
-#endif
-
-/* a type choosen by DEFINE */
-#ifdef HAVE_64BIT_INT_CUSTOM
-typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
-#else
-#ifdef HAS_STDINT_H
-#include "stdint.h"
-typedef uint64_t ZPOS64_T;
-#else
-
-/* Maximum unsigned 32-bit value used as placeholder for zip64 */
-#define MAXU32 0xffffffff
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 ZPOS64_T;
-#else
-typedef unsigned long long int ZPOS64_T;
-#endif
-#endif
-#endif
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ      (1)
-#define ZLIB_FILEFUNC_MODE_WRITE     (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE   (8)
-
-
-#ifndef ZCALLBACK
- #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-   #define ZCALLBACK CALLBACK
- #else
-   #define ZCALLBACK
- #endif
-#endif
-
-
-
-
-typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
-typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
-typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-
-
-/* here is the "old" 32 bits structure structure */
-typedef struct zlib_filefunc_def_s
-{
-    open_file_func      zopen_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell_file_func      ztell_file;
-    seek_file_func      zseek_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc_def;
-
-typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
-
-typedef struct zlib_filefunc64_def_s
-{
-    open64_file_func    zopen64_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell64_file_func    ztell64_file;
-    seek64_file_func    zseek64_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc64_def;
-
-void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-/* now internal definition, only for zip.c and unzip.h */
-typedef struct zlib_filefunc64_32_def_s
-{
-    zlib_filefunc64_def zfile_func64;
-    open_file_func      zopen32_file;
-    tell_file_func      ztell32_file;
-    seek_file_func      zseek32_file;
-} zlib_filefunc64_32_def;
-
-
-#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
-#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
-/* #define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) */
-/* #define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) */
-#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
-#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
-
-voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
-long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
-ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
-
-void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
-
-#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
-#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
-#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 694
library/include/xlsxwriter/third_party/queue.h

@@ -1,694 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)queue.h	8.5 (Berkeley) 8/20/94
- * $FreeBSD$
- */
-
-#ifndef _SYS_QUEUE_H_
-#define	_SYS_QUEUE_H_
-
-/* #include <sys/cdefs.h> */
-
-/*
- * This file defines four types of data structures: singly-linked lists,
- * singly-linked tail queues, lists and tail queues.
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction.  Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A singly-linked tail queue is headed by a pair of pointers, one to the
- * head of the list and the other to the tail of the list. The elements are
- * singly linked for minimum space and pointer manipulation overhead at the
- * expense of O(n) removal for arbitrary elements. New elements can be added
- * to the list after an existing element, at the head of the list, or at the
- * end of the list. Elements being removed from the head of the tail queue
- * should use the explicit macro for this purpose for optimum efficiency.
- * A singly-linked tail queue may only be traversed in the forward direction.
- * Singly-linked tail queues are ideal for applications with large datasets
- * and few or no removals or for implementing a FIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may be traversed in either direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *
- *
- *				SLIST	LIST	STAILQ	TAILQ
- * _HEAD			+	+	+	+
- * _HEAD_INITIALIZER		+	+	+	+
- * _ENTRY			+	+	+	+
- * _INIT			+	+	+	+
- * _EMPTY			+	+	+	+
- * _FIRST			+	+	+	+
- * _NEXT			+	+	+	+
- * _PREV			-	+	-	+
- * _LAST			-	-	+	+
- * _FOREACH			+	+	+	+
- * _FOREACH_FROM		+	+	+	+
- * _FOREACH_SAFE		+	+	+	+
- * _FOREACH_FROM_SAFE		+	+	+	+
- * _FOREACH_REVERSE		-	-	-	+
- * _FOREACH_REVERSE_FROM	-	-	-	+
- * _FOREACH_REVERSE_SAFE	-	-	-	+
- * _FOREACH_REVERSE_FROM_SAFE	-	-	-	+
- * _INSERT_HEAD			+	+	+	+
- * _INSERT_BEFORE		-	+	-	+
- * _INSERT_AFTER		+	+	+	+
- * _INSERT_TAIL			-	-	+	+
- * _CONCAT			-	-	+	+
- * _REMOVE_AFTER		+	-	+	-
- * _REMOVE_HEAD			+	-	+	-
- * _REMOVE			+	+	+	+
- * _SWAP			+	+	+	+
- *
- */
-#ifdef QUEUE_MACRO_DEBUG
-/* Store the last 2 places the queue element or head was altered */
-struct qm_trace {
-	unsigned long	 lastline;
-	unsigned long	 prevline;
-	const char	*lastfile;
-	const char	*prevfile;
-};
-
-#define	TRACEBUF	struct qm_trace trace;
-#define	TRACEBUF_INITIALIZER	{ __FILE__, __LINE__, NULL, 0 } ,
-#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
-#define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
-
-#define	QMD_TRACE_HEAD(head) do {					\
-	(head)->trace.prevline = (head)->trace.lastline;		\
-	(head)->trace.prevfile = (head)->trace.lastfile;		\
-	(head)->trace.lastline = __LINE__;				\
-	(head)->trace.lastfile = __FILE__;				\
-} while (0)
-
-#define	QMD_TRACE_ELEM(elem) do {					\
-	(elem)->trace.prevline = (elem)->trace.lastline;		\
-	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
-	(elem)->trace.lastline = __LINE__;				\
-	(elem)->trace.lastfile = __FILE__;				\
-} while (0)
-
-#else
-#define	QMD_TRACE_ELEM(elem)
-#define	QMD_TRACE_HEAD(head)
-#define	QMD_SAVELINK(name, link)
-#define	TRACEBUF
-#define	TRACEBUF_INITIALIZER
-#define	TRASHIT(x)
-#endif	/* QUEUE_MACRO_DEBUG */
-
-/*
- * Singly-linked List declarations.
- */
-#define	SLIST_HEAD(name, type)						\
-struct name {								\
-	struct type *slh_first;	/* first element */			\
-}
-
-#define	SLIST_HEAD_INITIALIZER(head)					\
-	{ NULL }
-
-#define	SLIST_ENTRY(type)						\
-struct {								\
-	struct type *sle_next;	/* next element */			\
-}
-
-/*
- * Singly-linked List functions.
- */
-#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
-
-#define	SLIST_FIRST(head)	((head)->slh_first)
-
-#define	SLIST_FOREACH(var, head, field)					\
-	for ((var) = SLIST_FIRST((head));				\
-	    (var);							\
-	    (var) = SLIST_NEXT((var), field))
-
-#define	SLIST_FOREACH_FROM(var, head, field)				\
-	for ((var) = ((var) ? (var) : SLIST_FIRST((head)));		\
-	    (var);							\
-	    (var) = SLIST_NEXT((var), field))
-
-#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
-	for ((var) = SLIST_FIRST((head));				\
-	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)			\
-	for ((var) = ((var) ? (var) : SLIST_FIRST((head)));		\
-	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
-	for ((varp) = &SLIST_FIRST((head));				\
-	    ((var) = *(varp)) != NULL;					\
-	    (varp) = &SLIST_NEXT((var), field))
-
-#define	SLIST_INIT(head) do {						\
-	SLIST_FIRST((head)) = NULL;					\
-} while (0)
-
-#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
-	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
-	SLIST_NEXT((slistelm), field) = (elm);				\
-} while (0)
-
-#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
-	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
-	SLIST_FIRST((head)) = (elm);					\
-} while (0)
-
-#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
-
-#define	SLIST_REMOVE(head, elm, type, field) do {			\
-	QMD_SAVELINK(oldnext, (elm)->field.sle_next);			\
-	if (SLIST_FIRST((head)) == (elm)) {				\
-		SLIST_REMOVE_HEAD((head), field);			\
-	}								\
-	else {								\
-		struct type *curelm = SLIST_FIRST((head));		\
-		while (SLIST_NEXT(curelm, field) != (elm))		\
-			curelm = SLIST_NEXT(curelm, field);		\
-		SLIST_REMOVE_AFTER(curelm, field);			\
-	}								\
-	TRASHIT(*oldnext);						\
-} while (0)
-
-#define SLIST_REMOVE_AFTER(elm, field) do {				\
-	SLIST_NEXT(elm, field) =					\
-	    SLIST_NEXT(SLIST_NEXT(elm, field), field);			\
-} while (0)
-
-#define	SLIST_REMOVE_HEAD(head, field) do {				\
-	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
-} while (0)
-
-#define SLIST_SWAP(head1, head2, type) do {				\
-	struct type *swap_first = SLIST_FIRST(head1);			\
-	SLIST_FIRST(head1) = SLIST_FIRST(head2);			\
-	SLIST_FIRST(head2) = swap_first;				\
-} while (0)
-
-/*
- * Singly-linked Tail queue declarations.
- */
-#define	STAILQ_HEAD(name, type)						\
-struct name {								\
-	struct type *stqh_first;/* first element */			\
-	struct type **stqh_last;/* addr of last next element */		\
-}
-
-#define	STAILQ_HEAD_INITIALIZER(head)					\
-	{ NULL, &(head).stqh_first }
-
-#define	STAILQ_ENTRY(type)						\
-struct {								\
-	struct type *stqe_next;	/* next element */			\
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define	STAILQ_CONCAT(head1, head2) do {				\
-	if (!STAILQ_EMPTY((head2))) {					\
-		*(head1)->stqh_last = (head2)->stqh_first;		\
-		(head1)->stqh_last = (head2)->stqh_last;		\
-		STAILQ_INIT((head2));					\
-	}								\
-} while (0)
-
-#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
-
-#define	STAILQ_FIRST(head)	((head)->stqh_first)
-
-#define	STAILQ_FOREACH(var, head, field)				\
-	for((var) = STAILQ_FIRST((head));				\
-	   (var);							\
-	   (var) = STAILQ_NEXT((var), field))
-
-#define	STAILQ_FOREACH_FROM(var, head, field)				\
-	for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));		\
-	   (var);							\
-	   (var) = STAILQ_NEXT((var), field))
-
-#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
-	for ((var) = STAILQ_FIRST((head));				\
-	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)		\
-	for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));		\
-	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	STAILQ_INIT(head) do {						\
-	STAILQ_FIRST((head)) = NULL;					\
-	(head)->stqh_last = &STAILQ_FIRST((head));			\
-} while (0)
-
-#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
-	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
-		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
-	STAILQ_NEXT((tqelm), field) = (elm);				\
-} while (0)
-
-#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
-	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
-		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
-	STAILQ_FIRST((head)) = (elm);					\
-} while (0)
-
-#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
-	STAILQ_NEXT((elm), field) = NULL;				\
-	*(head)->stqh_last = (elm);					\
-	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
-} while (0)
-
-#define	STAILQ_LAST(head, type, field)					\
-	(STAILQ_EMPTY((head)) ? NULL :					\
-	    __containerof((head)->stqh_last, struct type, field.stqe_next))
-
-#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
-
-#define	STAILQ_REMOVE(head, elm, type, field) do {			\
-	QMD_SAVELINK(oldnext, (elm)->field.stqe_next);			\
-	if (STAILQ_FIRST((head)) == (elm)) {				\
-		STAILQ_REMOVE_HEAD((head), field);			\
-	}								\
-	else {								\
-		struct type *curelm = STAILQ_FIRST((head));		\
-		while (STAILQ_NEXT(curelm, field) != (elm))		\
-			curelm = STAILQ_NEXT(curelm, field);		\
-		STAILQ_REMOVE_AFTER(head, curelm, field);		\
-	}								\
-	TRASHIT(*oldnext);						\
-} while (0)
-
-#define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
-	if ((STAILQ_NEXT(elm, field) =					\
-	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
-		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
-} while (0)
-
-#define	STAILQ_REMOVE_HEAD(head, field) do {				\
-	if ((STAILQ_FIRST((head)) =					\
-	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
-		(head)->stqh_last = &STAILQ_FIRST((head));		\
-} while (0)
-
-#define STAILQ_SWAP(head1, head2, type) do {				\
-	struct type *swap_first = STAILQ_FIRST(head1);			\
-	struct type **swap_last = (head1)->stqh_last;			\
-	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
-	(head1)->stqh_last = (head2)->stqh_last;			\
-	STAILQ_FIRST(head2) = swap_first;				\
-	(head2)->stqh_last = swap_last;					\
-	if (STAILQ_EMPTY(head1))					\
-		(head1)->stqh_last = &STAILQ_FIRST(head1);		\
-	if (STAILQ_EMPTY(head2))					\
-		(head2)->stqh_last = &STAILQ_FIRST(head2);		\
-} while (0)
-
-
-/*
- * List declarations.
- */
-#define	LIST_HEAD(name, type)						\
-struct name {								\
-	struct type *lh_first;	/* first element */			\
-}
-
-#define	LIST_HEAD_INITIALIZER(head)					\
-	{ NULL }
-
-#define	LIST_ENTRY(type)						\
-struct {								\
-	struct type *le_next;	/* next element */			\
-	struct type **le_prev;	/* address of previous next element */	\
-}
-
-/*
- * List functions.
- */
-
-#if (defined(_KERNEL) && defined(INVARIANTS))
-#define	QMD_LIST_CHECK_HEAD(head, field) do {				\
-	if (LIST_FIRST((head)) != NULL &&				\
-	    LIST_FIRST((head))->field.le_prev !=			\
-	     &LIST_FIRST((head)))					\
-		panic("Bad list head %p first->prev != head", (head));	\
-} while (0)
-
-#define	QMD_LIST_CHECK_NEXT(elm, field) do {				\
-	if (LIST_NEXT((elm), field) != NULL &&				\
-	    LIST_NEXT((elm), field)->field.le_prev !=			\
-	     &((elm)->field.le_next))					\
-	     	panic("Bad link elm %p next->prev != elm", (elm));	\
-} while (0)
-
-#define	QMD_LIST_CHECK_PREV(elm, field) do {				\
-	if (*(elm)->field.le_prev != (elm))				\
-		panic("Bad link elm %p prev->next != elm", (elm));	\
-} while (0)
-#else
-#define	QMD_LIST_CHECK_HEAD(head, field)
-#define	QMD_LIST_CHECK_NEXT(elm, field)
-#define	QMD_LIST_CHECK_PREV(elm, field)
-#endif /* (_KERNEL && INVARIANTS) */
-
-#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
-
-#define	LIST_FIRST(head)	((head)->lh_first)
-
-#define	LIST_FOREACH(var, head, field)					\
-	for ((var) = LIST_FIRST((head));				\
-	    (var);							\
-	    (var) = LIST_NEXT((var), field))
-
-#define	LIST_FOREACH_FROM(var, head, field)				\
-	for ((var) = ((var) ? (var) : LIST_FIRST((head)));		\
-	    (var);							\
-	    (var) = LIST_NEXT((var), field))
-
-#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
-	for ((var) = LIST_FIRST((head));				\
-	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	LIST_FOREACH_FROM_SAFE(var, head, field, tvar)			\
-	for ((var) = ((var) ? (var) : LIST_FIRST((head)));		\
-	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	LIST_INIT(head) do {						\
-	LIST_FIRST((head)) = NULL;					\
-} while (0)
-
-#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
-	QMD_LIST_CHECK_NEXT(listelm, field);				\
-	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
-		LIST_NEXT((listelm), field)->field.le_prev =		\
-		    &LIST_NEXT((elm), field);				\
-	LIST_NEXT((listelm), field) = (elm);				\
-	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
-} while (0)
-
-#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
-	QMD_LIST_CHECK_PREV(listelm, field);				\
-	(elm)->field.le_prev = (listelm)->field.le_prev;		\
-	LIST_NEXT((elm), field) = (listelm);				\
-	*(listelm)->field.le_prev = (elm);				\
-	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
-} while (0)
-
-#define	LIST_INSERT_HEAD(head, elm, field) do {				\
-	QMD_LIST_CHECK_HEAD((head), field);				\
-	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
-		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
-	LIST_FIRST((head)) = (elm);					\
-	(elm)->field.le_prev = &LIST_FIRST((head));			\
-} while (0)
-
-#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
-
-#define	LIST_PREV(elm, head, type, field)				\
-	((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :		\
-	    __containerof((elm)->field.le_prev, struct type, field.le_next))
-
-#define	LIST_REMOVE(elm, field) do {					\
-	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
-	QMD_SAVELINK(oldprev, (elm)->field.le_prev);			\
-	QMD_LIST_CHECK_NEXT(elm, field);				\
-	QMD_LIST_CHECK_PREV(elm, field);				\
-	if (LIST_NEXT((elm), field) != NULL)				\
-		LIST_NEXT((elm), field)->field.le_prev = 		\
-		    (elm)->field.le_prev;				\
-	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
-	TRASHIT(*oldnext);						\
-	TRASHIT(*oldprev);						\
-} while (0)
-
-#define LIST_SWAP(head1, head2, type, field) do {			\
-	struct type *swap_tmp = LIST_FIRST((head1));			\
-	LIST_FIRST((head1)) = LIST_FIRST((head2));			\
-	LIST_FIRST((head2)) = swap_tmp;					\
-	if ((swap_tmp = LIST_FIRST((head1))) != NULL)			\
-		swap_tmp->field.le_prev = &LIST_FIRST((head1));		\
-	if ((swap_tmp = LIST_FIRST((head2))) != NULL)			\
-		swap_tmp->field.le_prev = &LIST_FIRST((head2));		\
-} while (0)
-
-/*
- * Tail queue declarations.
- */
-#define	TAILQ_HEAD(name, type)						\
-struct name {								\
-	struct type *tqh_first;	/* first element */			\
-	struct type **tqh_last;	/* addr of last next element */		\
-	TRACEBUF							\
-}
-
-#define	TAILQ_HEAD_INITIALIZER(head)					\
-	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
-
-#define	TAILQ_ENTRY(type)						\
-struct {								\
-	struct type *tqe_next;	/* next element */			\
-	struct type **tqe_prev;	/* address of previous next element */	\
-	TRACEBUF							\
-}
-
-/*
- * Tail queue functions.
- */
-#if (defined(_KERNEL) && defined(INVARIANTS))
-#define	QMD_TAILQ_CHECK_HEAD(head, field) do {				\
-	if (!TAILQ_EMPTY(head) &&					\
-	    TAILQ_FIRST((head))->field.tqe_prev !=			\
-	     &TAILQ_FIRST((head)))					\
-		panic("Bad tailq head %p first->prev != head", (head));	\
-} while (0)
-
-#define	QMD_TAILQ_CHECK_TAIL(head, field) do {				\
-	if (*(head)->tqh_last != NULL)					\
-	    	panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); 	\
-} while (0)
-
-#define	QMD_TAILQ_CHECK_NEXT(elm, field) do {				\
-	if (TAILQ_NEXT((elm), field) != NULL &&				\
-	    TAILQ_NEXT((elm), field)->field.tqe_prev !=			\
-	     &((elm)->field.tqe_next))					\
-		panic("Bad link elm %p next->prev != elm", (elm));	\
-} while (0)
-
-#define	QMD_TAILQ_CHECK_PREV(elm, field) do {				\
-	if (*(elm)->field.tqe_prev != (elm))				\
-		panic("Bad link elm %p prev->next != elm", (elm));	\
-} while (0)
-#else
-#define	QMD_TAILQ_CHECK_HEAD(head, field)
-#define	QMD_TAILQ_CHECK_TAIL(head, headname)
-#define	QMD_TAILQ_CHECK_NEXT(elm, field)
-#define	QMD_TAILQ_CHECK_PREV(elm, field)
-#endif /* (_KERNEL && INVARIANTS) */
-
-#define	TAILQ_CONCAT(head1, head2, field) do {				\
-	if (!TAILQ_EMPTY(head2)) {					\
-		*(head1)->tqh_last = (head2)->tqh_first;		\
-		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
-		(head1)->tqh_last = (head2)->tqh_last;			\
-		TAILQ_INIT((head2));					\
-		QMD_TRACE_HEAD(head1);					\
-		QMD_TRACE_HEAD(head2);					\
-	}								\
-} while (0)
-
-#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
-
-#define	TAILQ_FIRST(head)	((head)->tqh_first)
-
-#define	TAILQ_FOREACH(var, head, field)					\
-	for ((var) = TAILQ_FIRST((head));				\
-	    (var);							\
-	    (var) = TAILQ_NEXT((var), field))
-
-#define	TAILQ_FOREACH_FROM(var, head, field)				\
-	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
-	    (var);							\
-	    (var) = TAILQ_NEXT((var), field))
-
-#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
-	for ((var) = TAILQ_FIRST((head));				\
-	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)			\
-	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
-	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
-	    (var) = (tvar))
-
-#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
-	for ((var) = TAILQ_LAST((head), headname);			\
-	    (var);							\
-	    (var) = TAILQ_PREV((var), headname, field))
-
-#define	TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)		\
-	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
-	    (var);							\
-	    (var) = TAILQ_PREV((var), headname, field))
-
-#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
-	for ((var) = TAILQ_LAST((head), headname);			\
-	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
-	    (var) = (tvar))
-
-#define	TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
-	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
-	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
-	    (var) = (tvar))
-
-#define	TAILQ_INIT(head) do {						\
-	TAILQ_FIRST((head)) = NULL;					\
-	(head)->tqh_last = &TAILQ_FIRST((head));			\
-	QMD_TRACE_HEAD(head);						\
-} while (0)
-
-#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
-	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
-		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
-		    &TAILQ_NEXT((elm), field);				\
-	else {								\
-		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
-		QMD_TRACE_HEAD(head);					\
-	}								\
-	TAILQ_NEXT((listelm), field) = (elm);				\
-	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
-	QMD_TRACE_ELEM(&(elm)->field);					\
-	QMD_TRACE_ELEM(&listelm->field);				\
-} while (0)
-
-#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
-	QMD_TAILQ_CHECK_PREV(listelm, field);				\
-	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
-	TAILQ_NEXT((elm), field) = (listelm);				\
-	*(listelm)->field.tqe_prev = (elm);				\
-	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
-	QMD_TRACE_ELEM(&(elm)->field);					\
-	QMD_TRACE_ELEM(&listelm->field);				\
-} while (0)
-
-#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
-	QMD_TAILQ_CHECK_HEAD(head, field);				\
-	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
-		TAILQ_FIRST((head))->field.tqe_prev =			\
-		    &TAILQ_NEXT((elm), field);				\
-	else								\
-		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
-	TAILQ_FIRST((head)) = (elm);					\
-	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
-	QMD_TRACE_HEAD(head);						\
-	QMD_TRACE_ELEM(&(elm)->field);					\
-} while (0)
-
-#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
-	QMD_TAILQ_CHECK_TAIL(head, field);				\
-	TAILQ_NEXT((elm), field) = NULL;				\
-	(elm)->field.tqe_prev = (head)->tqh_last;			\
-	*(head)->tqh_last = (elm);					\
-	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
-	QMD_TRACE_HEAD(head);						\
-	QMD_TRACE_ELEM(&(elm)->field);					\
-} while (0)
-
-#define	TAILQ_LAST(head, headname)					\
-	(*(((struct headname *)((head)->tqh_last))->tqh_last))
-
-#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define	TAILQ_PREV(elm, headname, field)				\
-	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-#define	TAILQ_REMOVE(head, elm, field) do {				\
-	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
-	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
-	QMD_TAILQ_CHECK_NEXT(elm, field);				\
-	QMD_TAILQ_CHECK_PREV(elm, field);				\
-	if ((TAILQ_NEXT((elm), field)) != NULL)				\
-		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
-		    (elm)->field.tqe_prev;				\
-	else {								\
-		(head)->tqh_last = (elm)->field.tqe_prev;		\
-		QMD_TRACE_HEAD(head);					\
-	}								\
-	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
-	TRASHIT(*oldnext);						\
-	TRASHIT(*oldprev);						\
-	QMD_TRACE_ELEM(&(elm)->field);					\
-} while (0)
-
-#define TAILQ_SWAP(head1, head2, type, field) do {			\
-	struct type *swap_first = (head1)->tqh_first;			\
-	struct type **swap_last = (head1)->tqh_last;			\
-	(head1)->tqh_first = (head2)->tqh_first;			\
-	(head1)->tqh_last = (head2)->tqh_last;				\
-	(head2)->tqh_first = swap_first;				\
-	(head2)->tqh_last = swap_last;					\
-	if ((swap_first = (head1)->tqh_first) != NULL)			\
-		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
-	else								\
-		(head1)->tqh_last = &(head1)->tqh_first;		\
-	if ((swap_first = (head2)->tqh_first) != NULL)			\
-		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
-	else								\
-		(head2)->tqh_last = &(head2)->tqh_first;		\
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */

+ 0 - 53
library/include/xlsxwriter/third_party/tmpfileplus.h

@@ -1,53 +0,0 @@
-/* $Id: tmpfileplus.h $ */
-/*
- * $Date: 2016-06-01 03:31Z $
- * $Revision: 2.0.0 $
- * $Author: dai $
- */
-
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
- * <http://www.di-mgt.com.au/contact/>.
- */
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifndef TMPFILEPLUS_H_
-#define TMPFILEPLUS_H_
-
-#include <stdio.h>
-
-/** Create a unique temporary file.
-@param dir (optional) directory to create file. If NULL use default TMP directory.
-@param prefix (optional) prefix for file name. If NULL use "tmp.".
-@param pathname (optional) pointer to a buffer to receive the temp filename. 
-	Allocated using `malloc()`; user to free. Ignored if NULL.
-@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 
-	Otherwise file is automatically deleted when closed.
-@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
-@exception ENOMEM Not enough memory to allocate filename.
-*/
-FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
-
-
-/** Create a unique temporary file with filename stored in a fixed-length buffer.
-@param dir (optional) directory to create file. If NULL use default directory.
-@param prefix (optional) prefix for file name. If NULL use "tmp.".
-@param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL.
-@param pathsize Size of buffer to receive filename and its terminating null character.
-@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing.
-	Otherwise file is automatically deleted when closed.
-@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
-@exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
-*/
-FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
-
-#define TMPFILE_KEEP 1
-
-#endif /* end TMPFILEPLUS_H_ */

+ 0 - 801
library/include/xlsxwriter/third_party/tree.h

@@ -1,801 +0,0 @@
-/*	$NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $	*/
-/*	$OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $	*/
-/* $FreeBSD$ */
-
-/*-
- * Copyright 2002 Niels Provos <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef	_SYS_TREE_H_
-#define	_SYS_TREE_H_
-
-/* #include <sys/cdefs.h> */
-
-/*
- * This file defines data structures for different types of trees:
- * splay trees and red-black trees.
- *
- * A splay tree is a self-organizing data structure.  Every operation
- * on the tree causes a splay to happen.  The splay moves the requested
- * node to the root of the tree and partly rebalances it.
- *
- * This has the benefit that request locality causes faster lookups as
- * the requested nodes move to the top of the tree.  On the other hand,
- * every lookup causes memory writes.
- *
- * The Balance Theorem bounds the total access time for m operations
- * and n inserts on an initially empty tree as O((m + n)lg n).  The
- * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
- *
- * A red-black tree is a binary search tree with the node color as an
- * extra attribute.  It fulfills a set of conditions:
- *	- every search path from the root to a leaf consists of the
- *	  same number of black nodes,
- *	- each red node (except for the root) has a black parent,
- *	- each leaf node is black.
- *
- * Every operation on a red-black tree is bounded as O(lg n).
- * The maximum height of a red-black tree is 2lg (n+1).
- */
-
-#define SPLAY_HEAD(name, type)						\
-struct name {								\
-	struct type *sph_root; /* root of the tree */			\
-}
-
-#define SPLAY_INITIALIZER(root)						\
-	{ NULL }
-
-#define SPLAY_INIT(root) do {						\
-	(root)->sph_root = NULL;					\
-} while (/*CONSTCOND*/ 0)
-
-#define SPLAY_ENTRY(type)						\
-struct {								\
-	struct type *spe_left; /* left element */			\
-	struct type *spe_right; /* right element */			\
-}
-
-#define SPLAY_LEFT(elm, field)		(elm)->field.spe_left
-#define SPLAY_RIGHT(elm, field)		(elm)->field.spe_right
-#define SPLAY_ROOT(head)		(head)->sph_root
-#define SPLAY_EMPTY(head)		(SPLAY_ROOT(head) == NULL)
-
-/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
-#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {			\
-	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);	\
-	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
-	(head)->sph_root = tmp;						\
-} while (/*CONSTCOND*/ 0)
-
-#define SPLAY_ROTATE_LEFT(head, tmp, field) do {			\
-	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);	\
-	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
-	(head)->sph_root = tmp;						\
-} while (/*CONSTCOND*/ 0)
-
-#define SPLAY_LINKLEFT(head, tmp, field) do {				\
-	SPLAY_LEFT(tmp, field) = (head)->sph_root;			\
-	tmp = (head)->sph_root;						\
-	(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);		\
-} while (/*CONSTCOND*/ 0)
-
-#define SPLAY_LINKRIGHT(head, tmp, field) do {				\
-	SPLAY_RIGHT(tmp, field) = (head)->sph_root;			\
-	tmp = (head)->sph_root;						\
-	(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);	\
-} while (/*CONSTCOND*/ 0)
-
-#define SPLAY_ASSEMBLE(head, node, left, right, field) do {		\
-	SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);	\
-	SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
-	SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);	\
-	SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);	\
-} while (/*CONSTCOND*/ 0)
-
-/* Generates prototypes and inline functions */
-
-#define SPLAY_PROTOTYPE(name, type, field, cmp)				\
-void name##_SPLAY(struct name *, struct type *);			\
-void name##_SPLAY_MINMAX(struct name *, int);				\
-struct type *name##_SPLAY_INSERT(struct name *, struct type *);		\
-struct type *name##_SPLAY_REMOVE(struct name *, struct type *);		\
-									\
-/* Finds the node with the same key as elm */				\
-static __inline struct type *						\
-name##_SPLAY_FIND(struct name *head, struct type *elm)			\
-{									\
-	if (SPLAY_EMPTY(head))						\
-		return(NULL);						\
-	name##_SPLAY(head, elm);					\
-	if ((cmp)(elm, (head)->sph_root) == 0)				\
-		return (head->sph_root);				\
-	return (NULL);							\
-}									\
-									\
-static __inline struct type *						\
-name##_SPLAY_NEXT(struct name *head, struct type *elm)			\
-{									\
-	name##_SPLAY(head, elm);					\
-	if (SPLAY_RIGHT(elm, field) != NULL) {				\
-		elm = SPLAY_RIGHT(elm, field);				\
-		while (SPLAY_LEFT(elm, field) != NULL) {		\
-			elm = SPLAY_LEFT(elm, field);			\
-		}							\
-	} else								\
-		elm = NULL;						\
-	return (elm);							\
-}									\
-									\
-static __inline struct type *						\
-name##_SPLAY_MIN_MAX(struct name *head, int val)			\
-{									\
-	name##_SPLAY_MINMAX(head, val);					\
-        return (SPLAY_ROOT(head));					\
-}
-
-/* Main splay operation.
- * Moves node close to the key of elm to top
- */
-#define SPLAY_GENERATE(name, type, field, cmp)				\
-struct type *								\
-name##_SPLAY_INSERT(struct name *head, struct type *elm)		\
-{									\
-    if (SPLAY_EMPTY(head)) {						\
-	    SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;	\
-    } else {								\
-	    int __comp;							\
-	    name##_SPLAY(head, elm);					\
-	    __comp = (cmp)(elm, (head)->sph_root);			\
-	    if(__comp < 0) {						\
-		    SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
-		    SPLAY_RIGHT(elm, field) = (head)->sph_root;		\
-		    SPLAY_LEFT((head)->sph_root, field) = NULL;		\
-	    } else if (__comp > 0) {					\
-		    SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
-		    SPLAY_LEFT(elm, field) = (head)->sph_root;		\
-		    SPLAY_RIGHT((head)->sph_root, field) = NULL;	\
-	    } else							\
-		    return ((head)->sph_root);				\
-    }									\
-    (head)->sph_root = (elm);						\
-    return (NULL);							\
-}									\
-									\
-struct type *								\
-name##_SPLAY_REMOVE(struct name *head, struct type *elm)		\
-{									\
-	struct type *__tmp;						\
-	if (SPLAY_EMPTY(head))						\
-		return (NULL);						\
-	name##_SPLAY(head, elm);					\
-	if ((cmp)(elm, (head)->sph_root) == 0) {			\
-		if (SPLAY_LEFT((head)->sph_root, field) == NULL) {	\
-			(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
-		} else {						\
-			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
-			(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
-			name##_SPLAY(head, elm);			\
-			SPLAY_RIGHT((head)->sph_root, field) = __tmp;	\
-		}							\
-		return (elm);						\
-	}								\
-	return (NULL);							\
-}									\
-									\
-void									\
-name##_SPLAY(struct name *head, struct type *elm)			\
-{									\
-	struct type __node, *__left, *__right, *__tmp;			\
-	int __comp;							\
-\
-	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
-	__left = __right = &__node;					\
-\
-	while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) {		\
-		if (__comp < 0) {					\
-			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
-			if (__tmp == NULL)				\
-				break;					\
-			if ((cmp)(elm, __tmp) < 0){			\
-				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
-				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
-					break;				\
-			}						\
-			SPLAY_LINKLEFT(head, __right, field);		\
-		} else if (__comp > 0) {				\
-			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
-			if (__tmp == NULL)				\
-				break;					\
-			if ((cmp)(elm, __tmp) > 0){			\
-				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
-				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
-					break;				\
-			}						\
-			SPLAY_LINKRIGHT(head, __left, field);		\
-		}							\
-	}								\
-	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
-}									\
-									\
-/* Splay with either the minimum or the maximum element			\
- * Used to find minimum or maximum element in tree.			\
- */									\
-void name##_SPLAY_MINMAX(struct name *head, int __comp) \
-{									\
-	struct type __node, *__left, *__right, *__tmp;			\
-\
-	SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
-	__left = __right = &__node;					\
-\
-	while (1) {							\
-		if (__comp < 0) {					\
-			__tmp = SPLAY_LEFT((head)->sph_root, field);	\
-			if (__tmp == NULL)				\
-				break;					\
-			if (__comp < 0){				\
-				SPLAY_ROTATE_RIGHT(head, __tmp, field);	\
-				if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
-					break;				\
-			}						\
-			SPLAY_LINKLEFT(head, __right, field);		\
-		} else if (__comp > 0) {				\
-			__tmp = SPLAY_RIGHT((head)->sph_root, field);	\
-			if (__tmp == NULL)				\
-				break;					\
-			if (__comp > 0) {				\
-				SPLAY_ROTATE_LEFT(head, __tmp, field);	\
-				if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
-					break;				\
-			}						\
-			SPLAY_LINKRIGHT(head, __left, field);		\
-		}							\
-	}								\
-	SPLAY_ASSEMBLE(head, &__node, __left, __right, field);		\
-}
-
-#define SPLAY_NEGINF	-1
-#define SPLAY_INF	1
-
-#define SPLAY_INSERT(name, x, y)	name##_SPLAY_INSERT(x, y)
-#define SPLAY_REMOVE(name, x, y)	name##_SPLAY_REMOVE(x, y)
-#define SPLAY_FIND(name, x, y)		name##_SPLAY_FIND(x, y)
-#define SPLAY_NEXT(name, x, y)		name##_SPLAY_NEXT(x, y)
-#define SPLAY_MIN(name, x)		(SPLAY_EMPTY(x) ? NULL	\
-					: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
-#define SPLAY_MAX(name, x)		(SPLAY_EMPTY(x) ? NULL	\
-					: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
-
-#define SPLAY_FOREACH(x, name, head)					\
-	for ((x) = SPLAY_MIN(name, head);				\
-	     (x) != NULL;						\
-	     (x) = SPLAY_NEXT(name, head, x))
-
-/* Macros that define a red-black tree */
-#define RB_HEAD(name, type)						\
-struct name {								\
-	struct type *rbh_root; /* root of the tree */			\
-}
-
-#define RB_INITIALIZER(root)						\
-	{ NULL }
-
-#define RB_INIT(root) do {						\
-	(root)->rbh_root = NULL;					\
-} while (/*CONSTCOND*/ 0)
-
-#define RB_BLACK	0
-#define RB_RED		1
-#define RB_ENTRY(type)							\
-struct {								\
-	struct type *rbe_left;		/* left element */		\
-	struct type *rbe_right;		/* right element */		\
-	struct type *rbe_parent;	/* parent element */		\
-	int rbe_color;			/* node color */		\
-}
-
-#define RB_LEFT(elm, field)		(elm)->field.rbe_left
-#define RB_RIGHT(elm, field)		(elm)->field.rbe_right
-#define RB_PARENT(elm, field)		(elm)->field.rbe_parent
-#define RB_COLOR(elm, field)		(elm)->field.rbe_color
-#define RB_ROOT(head)			(head)->rbh_root
-#define RB_EMPTY(head)			(RB_ROOT(head) == NULL)
-
-#define RB_SET(elm, parent, field) do {					\
-	RB_PARENT(elm, field) = parent;					\
-	RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;		\
-	RB_COLOR(elm, field) = RB_RED;					\
-} while (/*CONSTCOND*/ 0)
-
-#define RB_SET_BLACKRED(black, red, field) do {				\
-	RB_COLOR(black, field) = RB_BLACK;				\
-	RB_COLOR(red, field) = RB_RED;					\
-} while (/*CONSTCOND*/ 0)
-
-#ifndef RB_AUGMENT
-#define RB_AUGMENT(x)	do {} while (0)
-#endif
-
-#define RB_ROTATE_LEFT(head, elm, tmp, field) do {			\
-	(tmp) = RB_RIGHT(elm, field);					\
-	if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {	\
-		RB_PARENT(RB_LEFT(tmp, field), field) = (elm);		\
-	}								\
-	RB_AUGMENT(elm);						\
-	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {	\
-		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
-			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
-		else							\
-			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
-	} else								\
-		(head)->rbh_root = (tmp);				\
-	RB_LEFT(tmp, field) = (elm);					\
-	RB_PARENT(elm, field) = (tmp);					\
-	RB_AUGMENT(tmp);						\
-	if ((RB_PARENT(tmp, field)))					\
-		RB_AUGMENT(RB_PARENT(tmp, field));			\
-} while (/*CONSTCOND*/ 0)
-
-#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {			\
-	(tmp) = RB_LEFT(elm, field);					\
-	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {	\
-		RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);		\
-	}								\
-	RB_AUGMENT(elm);						\
-	if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {	\
-		if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))	\
-			RB_LEFT(RB_PARENT(elm, field), field) = (tmp);	\
-		else							\
-			RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);	\
-	} else								\
-		(head)->rbh_root = (tmp);				\
-	RB_RIGHT(tmp, field) = (elm);					\
-	RB_PARENT(elm, field) = (tmp);					\
-	RB_AUGMENT(tmp);						\
-	if ((RB_PARENT(tmp, field)))					\
-		RB_AUGMENT(RB_PARENT(tmp, field));			\
-} while (/*CONSTCOND*/ 0)
-
-/* Generates prototypes and inline functions */
-#define	RB_PROTOTYPE(name, type, field, cmp)				\
-	RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
-#define	RB_PROTOTYPE_STATIC(name, type, field, cmp)			\
-	RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
-#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)		\
-	RB_PROTOTYPE_INSERT_COLOR(name, type, attr);			\
-	RB_PROTOTYPE_REMOVE_COLOR(name, type, attr);			\
-	RB_PROTOTYPE_INSERT(name, type, attr);				\
-	RB_PROTOTYPE_REMOVE(name, type, attr);				\
-	RB_PROTOTYPE_FIND(name, type, attr);				\
-	RB_PROTOTYPE_NFIND(name, type, attr);				\
-	RB_PROTOTYPE_NEXT(name, type, attr);				\
-	RB_PROTOTYPE_PREV(name, type, attr);				\
-	RB_PROTOTYPE_MINMAX(name, type, attr);
-#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr)			\
-	attr void name##_RB_INSERT_COLOR(struct name *, struct type *)
-#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr)			\
-	attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *)
-#define RB_PROTOTYPE_REMOVE(name, type, attr)				\
-	attr struct type *name##_RB_REMOVE(struct name *, struct type *)
-#define RB_PROTOTYPE_INSERT(name, type, attr)				\
-	attr struct type *name##_RB_INSERT(struct name *, struct type *)
-#define RB_PROTOTYPE_FIND(name, type, attr)				\
-	attr struct type *name##_RB_FIND(struct name *, struct type *)
-#define RB_PROTOTYPE_NFIND(name, type, attr)				\
-	attr struct type *name##_RB_NFIND(struct name *, struct type *)
-#define RB_PROTOTYPE_NEXT(name, type, attr)				\
-	attr struct type *name##_RB_NEXT(struct type *)
-#define RB_PROTOTYPE_PREV(name, type, attr)				\
-	attr struct type *name##_RB_PREV(struct type *)
-#define RB_PROTOTYPE_MINMAX(name, type, attr)				\
-	attr struct type *name##_RB_MINMAX(struct name *, int)
-
-/* Main rb operation.
- * Moves node close to the key of elm to top
- */
-#define	RB_GENERATE(name, type, field, cmp)				\
-	RB_GENERATE_INTERNAL(name, type, field, cmp,)
-#define	RB_GENERATE_STATIC(name, type, field, cmp)			\
-	RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
-#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)		\
-	RB_GENERATE_INSERT_COLOR(name, type, field, attr)		\
-	RB_GENERATE_REMOVE_COLOR(name, type, field, attr)		\
-	RB_GENERATE_INSERT(name, type, field, cmp, attr)		\
-	RB_GENERATE_REMOVE(name, type, field, attr)			\
-	RB_GENERATE_FIND(name, type, field, cmp, attr)			\
-	RB_GENERATE_NFIND(name, type, field, cmp, attr)			\
-	RB_GENERATE_NEXT(name, type, field, attr)			\
-	RB_GENERATE_PREV(name, type, field, attr)			\
-	RB_GENERATE_MINMAX(name, type, field, attr)
-
-#define RB_GENERATE_INSERT_COLOR(name, type, field, attr)		\
-attr void								\
-name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
-{									\
-	struct type *parent, *gparent, *tmp;				\
-	while ((parent = RB_PARENT(elm, field)) != NULL &&		\
-	    RB_COLOR(parent, field) == RB_RED) {			\
-		gparent = RB_PARENT(parent, field);			\
-		if (parent == RB_LEFT(gparent, field)) {		\
-			tmp = RB_RIGHT(gparent, field);			\
-			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
-				RB_COLOR(tmp, field) = RB_BLACK;	\
-				RB_SET_BLACKRED(parent, gparent, field);\
-				elm = gparent;				\
-				continue;				\
-			}						\
-			if (RB_RIGHT(parent, field) == elm) {		\
-				RB_ROTATE_LEFT(head, parent, tmp, field);\
-				tmp = parent;				\
-				parent = elm;				\
-				elm = tmp;				\
-			}						\
-			RB_SET_BLACKRED(parent, gparent, field);	\
-			RB_ROTATE_RIGHT(head, gparent, tmp, field);	\
-		} else {						\
-			tmp = RB_LEFT(gparent, field);			\
-			if (tmp && RB_COLOR(tmp, field) == RB_RED) {	\
-				RB_COLOR(tmp, field) = RB_BLACK;	\
-				RB_SET_BLACKRED(parent, gparent, field);\
-				elm = gparent;				\
-				continue;				\
-			}						\
-			if (RB_LEFT(parent, field) == elm) {		\
-				RB_ROTATE_RIGHT(head, parent, tmp, field);\
-				tmp = parent;				\
-				parent = elm;				\
-				elm = tmp;				\
-			}						\
-			RB_SET_BLACKRED(parent, gparent, field);	\
-			RB_ROTATE_LEFT(head, gparent, tmp, field);	\
-		}							\
-	}								\
-	RB_COLOR(head->rbh_root, field) = RB_BLACK;			\
-}
-
-#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr)		\
-attr void								\
-name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
-{									\
-	struct type *tmp;						\
-	while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&	\
-	    elm != RB_ROOT(head)) {					\
-		if (RB_LEFT(parent, field) == elm) {			\
-			tmp = RB_RIGHT(parent, field);			\
-			if (RB_COLOR(tmp, field) == RB_RED) {		\
-				RB_SET_BLACKRED(tmp, parent, field);	\
-				RB_ROTATE_LEFT(head, parent, tmp, field);\
-				tmp = RB_RIGHT(parent, field);		\
-			}						\
-			if ((RB_LEFT(tmp, field) == NULL ||		\
-			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
-			    (RB_RIGHT(tmp, field) == NULL ||		\
-			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
-				RB_COLOR(tmp, field) = RB_RED;		\
-				elm = parent;				\
-				parent = RB_PARENT(elm, field);		\
-			} else {					\
-				if (RB_RIGHT(tmp, field) == NULL ||	\
-				    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
-					struct type *oleft;		\
-					if ((oleft = RB_LEFT(tmp, field)) \
-					    != NULL)			\
-						RB_COLOR(oleft, field) = RB_BLACK;\
-					RB_COLOR(tmp, field) = RB_RED;	\
-					RB_ROTATE_RIGHT(head, tmp, oleft, field);\
-					tmp = RB_RIGHT(parent, field);	\
-				}					\
-				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
-				RB_COLOR(parent, field) = RB_BLACK;	\
-				if (RB_RIGHT(tmp, field))		\
-					RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
-				RB_ROTATE_LEFT(head, parent, tmp, field);\
-				elm = RB_ROOT(head);			\
-				break;					\
-			}						\
-		} else {						\
-			tmp = RB_LEFT(parent, field);			\
-			if (RB_COLOR(tmp, field) == RB_RED) {		\
-				RB_SET_BLACKRED(tmp, parent, field);	\
-				RB_ROTATE_RIGHT(head, parent, tmp, field);\
-				tmp = RB_LEFT(parent, field);		\
-			}						\
-			if ((RB_LEFT(tmp, field) == NULL ||		\
-			    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
-			    (RB_RIGHT(tmp, field) == NULL ||		\
-			    RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
-				RB_COLOR(tmp, field) = RB_RED;		\
-				elm = parent;				\
-				parent = RB_PARENT(elm, field);		\
-			} else {					\
-				if (RB_LEFT(tmp, field) == NULL ||	\
-				    RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
-					struct type *oright;		\
-					if ((oright = RB_RIGHT(tmp, field)) \
-					    != NULL)			\
-						RB_COLOR(oright, field) = RB_BLACK;\
-					RB_COLOR(tmp, field) = RB_RED;	\
-					RB_ROTATE_LEFT(head, tmp, oright, field);\
-					tmp = RB_LEFT(parent, field);	\
-				}					\
-				RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
-				RB_COLOR(parent, field) = RB_BLACK;	\
-				if (RB_LEFT(tmp, field))		\
-					RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
-				RB_ROTATE_RIGHT(head, parent, tmp, field);\
-				elm = RB_ROOT(head);			\
-				break;					\
-			}						\
-		}							\
-	}								\
-	if (elm)							\
-		RB_COLOR(elm, field) = RB_BLACK;			\
-}
-
-#define RB_GENERATE_REMOVE(name, type, field, attr)			\
-attr struct type *							\
-name##_RB_REMOVE(struct name *head, struct type *elm)			\
-{									\
-	struct type *child, *parent, *old = elm;			\
-	int color;							\
-	if (RB_LEFT(elm, field) == NULL)				\
-		child = RB_RIGHT(elm, field);				\
-	else if (RB_RIGHT(elm, field) == NULL)				\
-		child = RB_LEFT(elm, field);				\
-	else {								\
-		struct type *left;					\
-		elm = RB_RIGHT(elm, field);				\
-		while ((left = RB_LEFT(elm, field)) != NULL)		\
-			elm = left;					\
-		child = RB_RIGHT(elm, field);				\
-		parent = RB_PARENT(elm, field);				\
-		color = RB_COLOR(elm, field);				\
-		if (child)						\
-			RB_PARENT(child, field) = parent;		\
-		if (parent) {						\
-			if (RB_LEFT(parent, field) == elm)		\
-				RB_LEFT(parent, field) = child;		\
-			else						\
-				RB_RIGHT(parent, field) = child;	\
-			RB_AUGMENT(parent);				\
-		} else							\
-			RB_ROOT(head) = child;				\
-		if (RB_PARENT(elm, field) == old)			\
-			parent = elm;					\
-		(elm)->field = (old)->field;				\
-		if (RB_PARENT(old, field)) {				\
-			if (RB_LEFT(RB_PARENT(old, field), field) == old)\
-				RB_LEFT(RB_PARENT(old, field), field) = elm;\
-			else						\
-				RB_RIGHT(RB_PARENT(old, field), field) = elm;\
-			RB_AUGMENT(RB_PARENT(old, field));		\
-		} else							\
-			RB_ROOT(head) = elm;				\
-		RB_PARENT(RB_LEFT(old, field), field) = elm;		\
-		if (RB_RIGHT(old, field))				\
-			RB_PARENT(RB_RIGHT(old, field), field) = elm;	\
-		if (parent) {						\
-			left = parent;					\
-			do {						\
-				RB_AUGMENT(left);			\
-			} while ((left = RB_PARENT(left, field)) != NULL); \
-		}							\
-		goto color;						\
-	}								\
-	parent = RB_PARENT(elm, field);					\
-	color = RB_COLOR(elm, field);					\
-	if (child)							\
-		RB_PARENT(child, field) = parent;			\
-	if (parent) {							\
-		if (RB_LEFT(parent, field) == elm)			\
-			RB_LEFT(parent, field) = child;			\
-		else							\
-			RB_RIGHT(parent, field) = child;		\
-		RB_AUGMENT(parent);					\
-	} else								\
-		RB_ROOT(head) = child;					\
-color:									\
-	if (color == RB_BLACK)						\
-		name##_RB_REMOVE_COLOR(head, parent, child);		\
-	return (old);							\
-}									\
-
-#define RB_GENERATE_INSERT(name, type, field, cmp, attr)		\
-/* Inserts a node into the RB tree */					\
-attr struct type *							\
-name##_RB_INSERT(struct name *head, struct type *elm)			\
-{									\
-	struct type *tmp;						\
-	struct type *parent = NULL;					\
-	int comp = 0;							\
-	tmp = RB_ROOT(head);						\
-	while (tmp) {							\
-		parent = tmp;						\
-		comp = (cmp)(elm, parent);				\
-		if (comp < 0)						\
-			tmp = RB_LEFT(tmp, field);			\
-		else if (comp > 0)					\
-			tmp = RB_RIGHT(tmp, field);			\
-		else							\
-			return (tmp);					\
-	}								\
-	RB_SET(elm, parent, field);					\
-	if (parent != NULL) {						\
-		if (comp < 0)						\
-			RB_LEFT(parent, field) = elm;			\
-		else							\
-			RB_RIGHT(parent, field) = elm;			\
-		RB_AUGMENT(parent);					\
-	} else								\
-		RB_ROOT(head) = elm;					\
-	name##_RB_INSERT_COLOR(head, elm);				\
-	return (NULL);							\
-}
-
-#define RB_GENERATE_FIND(name, type, field, cmp, attr)			\
-/* Finds the node with the same key as elm */				\
-attr struct type *							\
-name##_RB_FIND(struct name *head, struct type *elm)			\
-{									\
-	struct type *tmp = RB_ROOT(head);				\
-	int comp;							\
-	while (tmp) {							\
-		comp = cmp(elm, tmp);					\
-		if (comp < 0)						\
-			tmp = RB_LEFT(tmp, field);			\
-		else if (comp > 0)					\
-			tmp = RB_RIGHT(tmp, field);			\
-		else							\
-			return (tmp);					\
-	}								\
-	return (NULL);							\
-}
-
-#define RB_GENERATE_NFIND(name, type, field, cmp, attr)			\
-/* Finds the first node greater than or equal to the search key */	\
-attr struct type *							\
-name##_RB_NFIND(struct name *head, struct type *elm)			\
-{									\
-	struct type *tmp = RB_ROOT(head);				\
-	struct type *res = NULL;					\
-	int comp;							\
-	while (tmp) {							\
-		comp = cmp(elm, tmp);					\
-		if (comp < 0) {						\
-			res = tmp;					\
-			tmp = RB_LEFT(tmp, field);			\
-		}							\
-		else if (comp > 0)					\
-			tmp = RB_RIGHT(tmp, field);			\
-		else							\
-			return (tmp);					\
-	}								\
-	return (res);							\
-}
-
-#define RB_GENERATE_NEXT(name, type, field, attr)			\
-/* ARGSUSED */								\
-attr struct type *							\
-name##_RB_NEXT(struct type *elm)					\
-{									\
-	if (RB_RIGHT(elm, field)) {					\
-		elm = RB_RIGHT(elm, field);				\
-		while (RB_LEFT(elm, field))				\
-			elm = RB_LEFT(elm, field);			\
-	} else {							\
-		if (RB_PARENT(elm, field) &&				\
-		    (elm == RB_LEFT(RB_PARENT(elm, field), field)))	\
-			elm = RB_PARENT(elm, field);			\
-		else {							\
-			while (RB_PARENT(elm, field) &&			\
-			    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
-				elm = RB_PARENT(elm, field);		\
-			elm = RB_PARENT(elm, field);			\
-		}							\
-	}								\
-	return (elm);							\
-}
-
-#define RB_GENERATE_PREV(name, type, field, attr)			\
-/* ARGSUSED */								\
-attr struct type *							\
-name##_RB_PREV(struct type *elm)					\
-{									\
-	if (RB_LEFT(elm, field)) {					\
-		elm = RB_LEFT(elm, field);				\
-		while (RB_RIGHT(elm, field))				\
-			elm = RB_RIGHT(elm, field);			\
-	} else {							\
-		if (RB_PARENT(elm, field) &&				\
-		    (elm == RB_RIGHT(RB_PARENT(elm, field), field)))	\
-			elm = RB_PARENT(elm, field);			\
-		else {							\
-			while (RB_PARENT(elm, field) &&			\
-			    (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
-				elm = RB_PARENT(elm, field);		\
-			elm = RB_PARENT(elm, field);			\
-		}							\
-	}								\
-	return (elm);							\
-}
-
-#define RB_GENERATE_MINMAX(name, type, field, attr)			\
-attr struct type *							\
-name##_RB_MINMAX(struct name *head, int val)				\
-{									\
-	struct type *tmp = RB_ROOT(head);				\
-	struct type *parent = NULL;					\
-	while (tmp) {							\
-		parent = tmp;						\
-		if (val < 0)						\
-			tmp = RB_LEFT(tmp, field);			\
-		else							\
-			tmp = RB_RIGHT(tmp, field);			\
-	}								\
-	return (parent);						\
-}
-
-#define RB_NEGINF	-1
-#define RB_INF	1
-
-#define RB_INSERT(name, x, y)	name##_RB_INSERT(x, y)
-#define RB_REMOVE(name, x, y)	name##_RB_REMOVE(x, y)
-#define RB_FIND(name, x, y)	name##_RB_FIND(x, y)
-#define RB_NFIND(name, x, y)	name##_RB_NFIND(x, y)
-#define RB_NEXT(name, x, y)	name##_RB_NEXT(y)
-#define RB_PREV(name, x, y)	name##_RB_PREV(y)
-#define RB_MIN(name, x)		name##_RB_MINMAX(x, RB_NEGINF)
-#define RB_MAX(name, x)		name##_RB_MINMAX(x, RB_INF)
-
-#define RB_FOREACH(x, name, head)					\
-	for ((x) = RB_MIN(name, head);					\
-	     (x) != NULL;						\
-	     (x) = name##_RB_NEXT(x))
-
-#define RB_FOREACH_FROM(x, name, y)					\
-	for ((x) = (y);							\
-	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);	\
-	     (x) = (y))
-
-#define RB_FOREACH_SAFE(x, name, head, y)				\
-	for ((x) = RB_MIN(name, head);					\
-	    ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);	\
-	     (x) = (y))
-
-#define RB_FOREACH_REVERSE(x, name, head)				\
-	for ((x) = RB_MAX(name, head);					\
-	     (x) != NULL;						\
-	     (x) = name##_RB_PREV(x))
-
-#define RB_FOREACH_REVERSE_FROM(x, name, y)				\
-	for ((x) = (y);							\
-	    ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);	\
-	     (x) = (y))
-
-#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)			\
-	for ((x) = RB_MAX(name, head);					\
-	    ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);	\
-	     (x) = (y))
-
-#endif	/* _SYS_TREE_H_ */

+ 0 - 375
library/include/xlsxwriter/third_party/zip.h

@@ -1,375 +0,0 @@
-/* zip.h -- IO on .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         ---------------------------------------------------------------------------
-
-   Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-        ---------------------------------------------------------------------------
-
-        Changes
-
-        See header of zip.h
-
-*/
-
-/* Pragma added by libxlsxwriter to avoid warnings with -pedantic -ansi. */
-#ifndef _WIN32
-#pragma GCC system_header
-#endif
-
-#ifndef _zip12_H
-#define _zip12_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* #define HAVE_BZIP2 */
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-/* Encryption not required by libxlsxwriter. */
-#ifndef NOCRYPT
-#define NOCRYPT
-#endif
-#ifndef NOUNCRYPT
-#define NOUNCRYPT
-#endif
-
-#ifdef HAVE_BZIP2
-#include "bzlib.h"
-#endif
-
-#define Z_BZIP2ED 12
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK                          (0)
-#define ZIP_EOF                         (0)
-#define ZIP_ERRNO                       (Z_ERRNO)
-#define ZIP_PARAMERROR                  (-102)
-#define ZIP_BADZIPFILE                  (-103)
-#define ZIP_INTERNALERROR               (-104)
-
-#ifndef DEF_MEM_LEVEL
-#  if MAX_MEM_LEVEL >= 8
-#    define DEF_MEM_LEVEL 8
-#  else
-#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#  endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
-    tm_zip      tmz_date;       /* date in understandable format           */
-    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
-/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
-
-    uLong       internal_fa;    /* internal file attributes        2 bytes */
-    uLong       external_fa;    /* external file attributes        4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE        (0)
-#define APPEND_STATUS_CREATEAFTER   (1)
-#define APPEND_STATUS_ADDINZIP      (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
-/*
-  Create a zipfile.
-     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
-       an Unix computer "zlib/zlib113.zip".
-     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
-       will be created at the end of the file.
-         (useful if the file contain a self extractor code)
-     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
-       add files in existing zip (be sure you don't add file that doesn't exist)
-     If the zipfile cannot be opened, the return value is NULL.
-     Else, the return value is a zipFile Handle, usable with other function
-       of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
-   If you want delete file into a zipfile, you must open a zipfile, and create another
-   Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc_def* pzlib_filefunc_def));
-
-extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc64_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level));
-
-extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level,
-                       int zip64));
-
-/*
-  Open a file in the ZIP for writing.
-  filename : the filename in zip (if NULL, '-' without quote will be used
-  *zipfi contain supplemental information
-  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
-    contains the extrafield data the the local header
-  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
-    contains the extrafield data the the local header
-  if comment != NULL, comment contain the comment string
-  method contain the compression method (0 for store, Z_DEFLATED for deflate)
-  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
-                    this MUST be '1' if the uncompressed size is >= 0xffffffff.
-
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw));
-
-
-extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int zip64));
-/*
-  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting));
-
-extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            int zip64
-                                            ));
-
-/*
-  Same than zipOpenNewFileInZip2, except
-    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
-    password : crypting password (NULL for no crypting)
-    crcForCrypting : crc of file to compress (needed for crypting)
- */
-
-extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase
-                                            ));
-
-
-extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase,
-                                            int zip64
-                                            ));
-/*
-  Same than zipOpenNewFileInZip4, except
-    versionMadeBy : value for Version made by field
-    flag : value for flag field (compression level info will be added)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
-                       const void* buf,
-                       unsigned len));
-/*
-  Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
-  Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
-                                            uLong uncompressed_size,
-                                            uLong crc32));
-
-extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
-                                            ZPOS64_T uncompressed_size,
-                                            uLong crc32));
-
-/*
-  Close the current file in the zipfile, for file opened with
-    parameter raw=1 in zipOpenNewFileInZip2
-  uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
-                const char* global_comment));
-/*
-  Close the zipfile
-*/
-
-
-extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
-/*
-  zipRemoveExtraInfoBlock -  Added by Mathias Svensson
-
-  Remove extra information block from a extra information data for the local file header or central directory header
-
-  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
-
-  0x0001 is the signature header for the ZIP64 extra information blocks
-
-  usage.
-                        Remove ZIP64 Extra information from a central director extra field data
-              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
-
-                        Remove ZIP64 Extra information from a Local File Header extra field data
-        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip64_H */

+ 0 - 172
library/include/xlsxwriter/utility.h

@@ -1,172 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- */
-
-/**
- * @file utility.h
- *
- * @brief Utility functions for libxlsxwriter.
- *
- * <!-- Copyright 2014-2018, John McNamara, [email protected] -->
- *
- */
-
-#ifndef __LXW_UTILITY_H__
-#define __LXW_UTILITY_H__
-
-#include <stdint.h>
-#include "common.h"
-#include "xmlwriter.h"
-
-/**
- * @brief Convert an Excel `A1` cell string into a `(row, col)` pair.
- *
- * Convert an Excel `A1` cell string into a `(row, col)` pair.
- *
- * This is a little syntactic shortcut to help with worksheet layout:
- *
- * @code
- *      worksheet_write_string(worksheet, CELL("A1"), "Foo", NULL);
- *
- *      //Same as:
- *      worksheet_write_string(worksheet, 0, 0,       "Foo", NULL);
- * @endcode
- *
- * @note
- *
- * This macro shouldn't be used in performance critical situations since it
- * expands to two function calls.
- */
-#define CELL(cell) \
-    lxw_name_to_row(cell), lxw_name_to_col(cell)
-
-/**
- * @brief Convert an Excel `A:B` column range into a `(col1, col2)` pair.
- *
- * Convert an Excel `A:B` column range into a `(col1, col2)` pair.
- *
- * This is a little syntactic shortcut to help with worksheet layout:
- *
- * @code
- *     worksheet_set_column(worksheet, COLS("B:D"), 20, NULL, NULL);
- *
- *     // Same as:
- *     worksheet_set_column(worksheet, 1, 3,        20, NULL, NULL);
- * @endcode
- *
- */
-#define COLS(cols) \
-    lxw_name_to_col(cols), lxw_name_to_col_2(cols)
-
-/**
- * @brief Convert an Excel `A1:B2` range into a `(first_row, first_col,
- *        last_row, last_col)` sequence.
- *
- * Convert an Excel `A1:B2` range into a `(first_row, first_col, last_row,
- * last_col)` sequence.
- *
- * This is a little syntactic shortcut to help with worksheet layout.
- *
- * @code
- *     worksheet_print_area(worksheet, 0, 0, 41, 10); // A1:K42.
- *
- *     // Same as:
- *     worksheet_print_area(worksheet, RANGE("A1:K42"));
- * @endcode
- */
-#define RANGE(range) \
-    lxw_name_to_row(range), lxw_name_to_col(range), \
-    lxw_name_to_row_2(range), lxw_name_to_col_2(range)
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-/**
- * @brief Converts a libxlsxwriter error number to a string.
- *
- * The `%lxw_strerror` function converts a libxlsxwriter error number defined
- * by #lxw_error to a pointer to a string description of the error.
- * Similar to the standard library strerror(3) function.
- *
- * For example:
- *
- * @code
- *     lxw_error error = workbook_close(workbook);
- *
- *     if (error)
- *         printf("Error in workbook_close().\n"
- *                "Error %d = %s\n", error, lxw_strerror(error));
- * @endcode
- *
- * This would produce output like the following if the target file wasn't
- * writable:
- *
- *     Error in workbook_close().
- *     Error 2 = Error creating output xlsx file. Usually a permissions error.
- *
- * @param error_num The error number returned by a libxlsxwriter function.
- *
- * @return A pointer to a statically allocated string. Do not free.
- */
-char *lxw_strerror(lxw_error error_num);
-
-/* Create a quoted version of the worksheet name */
-char *lxw_quote_sheetname(const char *str);
-
-void lxw_col_to_name(char *col_name, lxw_col_t col_num, uint8_t absolute);
-
-void lxw_rowcol_to_cell(char *cell_name, lxw_row_t row, lxw_col_t col);
-
-void lxw_rowcol_to_cell_abs(char *cell_name,
-                            lxw_row_t row,
-                            lxw_col_t col, uint8_t abs_row, uint8_t abs_col);
-
-void lxw_rowcol_to_range(char *range,
-                         lxw_row_t first_row, lxw_col_t first_col,
-                         lxw_row_t last_row, lxw_col_t last_col);
-
-void lxw_rowcol_to_range_abs(char *range,
-                             lxw_row_t first_row, lxw_col_t first_col,
-                             lxw_row_t last_row, lxw_col_t last_col);
-
-void lxw_rowcol_to_formula_abs(char *formula, const char *sheetname,
-                               lxw_row_t first_row, lxw_col_t first_col,
-                               lxw_row_t last_row, lxw_col_t last_col);
-
-uint32_t lxw_name_to_row(const char *row_str);
-uint16_t lxw_name_to_col(const char *col_str);
-uint32_t lxw_name_to_row_2(const char *row_str);
-uint16_t lxw_name_to_col_2(const char *col_str);
-
-double lxw_datetime_to_excel_date(lxw_datetime *datetime, uint8_t date_1904);
-
-char *lxw_strdup(const char *str);
-char *lxw_strdup_formula(const char *formula);
-
-size_t lxw_utf8_strlen(const char *str);
-
-void lxw_str_tolower(char *str);
-
-FILE *lxw_tmpfile(char *tmpdir);
-
-/* Use a user defined function to format doubles in sprintf or else a simple
- * macro (the default). */
-#ifdef USE_DOUBLE_FUNCTION
-int lxw_sprintf_dbl(char *data, double number);
-#else
-#define lxw_sprintf_dbl(data, number) \
-        lxw_snprintf(data, LXW_ATTR_32, "%.16g", number)
-#endif
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_UTILITY_H__ */

+ 0 - 751
library/include/xlsxwriter/workbook.h

@@ -1,751 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- */
-
-/**
- * @page workbook_page The Workbook object
- *
- * The Workbook is the main object exposed by the libxlsxwriter library. It
- * represents the entire spreadsheet as you see it in Excel and internally it
- * represents the Excel file as it is written on disk.
- *
- * See @ref workbook.h for full details of the functionality.
- *
- * @file workbook.h
- *
- * @brief Functions related to creating an Excel xlsx workbook.
- *
- * The Workbook is the main object exposed by the libxlsxwriter library. It
- * represents the entire spreadsheet as you see it in Excel and internally it
- * represents the Excel file as it is written on disk.
- *
- * @code
- *     #include "xlsxwriter.h"
- *
- *     int main() {
- *
- *         lxw_workbook  *workbook  = workbook_new("filename.xlsx");
- *         lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
- *
- *         worksheet_write_string(worksheet, 0, 0, "Hello Excel", NULL);
- *
- *         return workbook_close(workbook);
- *     }
- * @endcode
- *
- * @image html workbook01.png
- *
- */
-#ifndef __LXW_WORKBOOK_H__
-#define __LXW_WORKBOOK_H__
-
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "worksheet.h"
-#include "chart.h"
-#include "shared_strings.h"
-#include "hash_table.h"
-#include "common.h"
-
-#define LXW_DEFINED_NAME_LENGTH 128
-
-/* Define the tree.h RB structs for the red-black head types. */
-RB_HEAD(lxw_worksheet_names, lxw_worksheet_name);
-
-/* Define the queue.h structs for the workbook lists. */
-STAILQ_HEAD(lxw_worksheets, lxw_worksheet);
-STAILQ_HEAD(lxw_charts, lxw_chart);
-TAILQ_HEAD(lxw_defined_names, lxw_defined_name);
-
-/* Struct to represent a worksheet name/pointer pair. */
-typedef struct lxw_worksheet_name {
-    const char *name;
-    lxw_worksheet *worksheet;
-
-    RB_ENTRY (lxw_worksheet_name) tree_pointers;
-} lxw_worksheet_name;
-
-/* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
- * warnings and to avoid portability issues with the _unused attribute. */
-#define LXW_RB_GENERATE_NAMES(name, type, field, cmp)     \
-    RB_GENERATE_INSERT_COLOR(name, type, field, static)   \
-    RB_GENERATE_REMOVE_COLOR(name, type, field, static)   \
-    RB_GENERATE_INSERT(name, type, field, cmp, static)    \
-    RB_GENERATE_REMOVE(name, type, field, static)         \
-    RB_GENERATE_FIND(name, type, field, cmp, static)      \
-    RB_GENERATE_NEXT(name, type, field, static)           \
-    RB_GENERATE_MINMAX(name, type, field, static)         \
-    /* Add unused struct to allow adding a semicolon */   \
-    struct lxw_rb_generate_names{int unused;}
-
-/**
- * @brief Macro to loop over all the worksheets in a workbook.
- *
- * This macro allows you to loop over all the worksheets that have been
- * added to a workbook. You must provide a lxw_worksheet pointer and
- * a pointer to the lxw_workbook:
- *
- * @code
- *    lxw_workbook  *workbook = workbook_new("test.xlsx");
- *
- *    lxw_worksheet *worksheet; // Generic worksheet pointer.
- *
- *    // Worksheet objects used in the program.
- *    lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL);
- *    lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL);
- *    lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, NULL);
- *
- *    // Iterate over the 3 worksheets and perform the same operation on each.
- *    LXW_FOREACH_WORKSHEET(worksheet, workbook) {
- *        worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
- *    }
- * @endcode
- */
-#define LXW_FOREACH_WORKSHEET(worksheet, workbook) \
-    STAILQ_FOREACH((worksheet), (workbook)->worksheets, list_pointers)
-
-/* Struct to represent a defined name. */
-typedef struct lxw_defined_name {
-    int16_t index;
-    uint8_t hidden;
-    char name[LXW_DEFINED_NAME_LENGTH];
-    char app_name[LXW_DEFINED_NAME_LENGTH];
-    char formula[LXW_DEFINED_NAME_LENGTH];
-    char normalised_name[LXW_DEFINED_NAME_LENGTH];
-    char normalised_sheetname[LXW_DEFINED_NAME_LENGTH];
-
-    /* List pointers for queue.h. */
-    TAILQ_ENTRY (lxw_defined_name) list_pointers;
-} lxw_defined_name;
-
-/**
- * Workbook document properties.
- */
-typedef struct lxw_doc_properties {
-    /** The title of the Excel Document. */
-    char *title;
-
-    /** The subject of the Excel Document. */
-    char *subject;
-
-    /** The author of the Excel Document. */
-    char *author;
-
-    /** The manager field of the Excel Document. */
-    char *manager;
-
-    /** The company field of the Excel Document. */
-    char *company;
-
-    /** The category of the Excel Document. */
-    char *category;
-
-    /** The keywords of the Excel Document. */
-    char *keywords;
-
-    /** The comment field of the Excel Document. */
-    char *comments;
-
-    /** The status of the Excel Document. */
-    char *status;
-
-    /** The hyperlink base url of the Excel Document. */
-    char *hyperlink_base;
-
-    time_t created;
-
-} lxw_doc_properties;
-
-/**
- * @brief Workbook options.
- *
- * Optional parameters when creating a new Workbook object via
- * workbook_new_opt().
- *
- * The following properties are supported:
- *
- * - `constant_memory`: Reduces the amount of data stored in memory so that
- *   large files can be written efficiently.
- *
- *   @note In this mode a row of data is written and then discarded when a
- *   cell in a new row is added via one of the `worksheet_write_*()`
- *   functions. Therefore, once this option is active, data should be written in
- *   sequential row order. For this reason the `worksheet_merge_range()`
- *   doesn't work in this mode. See also @ref ww_mem_constant.
- *
- * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior
- *   to assembling the final XLSX file. The temporary files are created in the
- *   system's temp directory. If the default temporary directory isn't
- *   accessible to your application, or doesn't contain enough space, you can
- *   specify an alternative location using the `tempdir` option.
- */
-typedef struct lxw_workbook_options {
-    /** Optimize the workbook to use constant memory for worksheets */
-    uint8_t constant_memory;
-
-    /** Directory to use for the temporary files created by libxlsxwriter. */
-    char *tmpdir;
-} lxw_workbook_options;
-
-/**
- * @brief Struct to represent an Excel workbook.
- *
- * The members of the lxw_workbook struct aren't modified directly. Instead
- * the workbook properties are set by calling the functions shown in
- * workbook.h.
- */
-typedef struct lxw_workbook {
-
-    FILE *file;
-    struct lxw_worksheets *worksheets;
-    struct lxw_worksheet_names *worksheet_names;
-    struct lxw_charts *charts;
-    struct lxw_charts *ordered_charts;
-    struct lxw_formats *formats;
-    struct lxw_defined_names *defined_names;
-    lxw_sst *sst;
-    lxw_doc_properties *properties;
-    struct lxw_custom_properties *custom_properties;
-
-    char *filename;
-    lxw_workbook_options options;
-
-    uint16_t num_sheets;
-    uint16_t first_sheet;
-    uint16_t active_sheet;
-    uint16_t num_xf_formats;
-    uint16_t num_format_count;
-    uint16_t drawing_count;
-
-    uint16_t font_count;
-    uint16_t border_count;
-    uint16_t fill_count;
-    uint8_t optimize;
-
-    uint8_t has_png;
-    uint8_t has_jpeg;
-    uint8_t has_bmp;
-
-    lxw_hash_table *used_xf_formats;
-
-} lxw_workbook;
-
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-/**
- * @brief Create a new workbook object.
- *
- * @param filename The name of the new Excel file to create.
- *
- * @return A lxw_workbook instance.
- *
- * The `%workbook_new()` constructor is used to create a new Excel workbook
- * with a given filename:
- *
- * @code
- *     lxw_workbook *workbook  = workbook_new("filename.xlsx");
- * @endcode
- *
- * When specifying a filename it is recommended that you use an `.xlsx`
- * extension or Excel will generate a warning when opening the file.
- *
- */
-lxw_workbook *workbook_new(const char *filename);
-
-/**
- * @brief Create a new workbook object, and set the workbook options.
- *
- * @param filename The name of the new Excel file to create.
- * @param options  Workbook options.
- *
- * @return A lxw_workbook instance.
- *
- * This function is the same as the `workbook_new()` constructor but allows
- * additional options to be set.
- *
- * @code
- *    lxw_workbook_options options = {.constant_memory = 1,
- *                                    .tmpdir = "C:\\Temp"};
- *
- *    lxw_workbook  *workbook  = workbook_new_opt("filename.xlsx", &options);
- * @endcode
- *
- * The options that can be set via #lxw_workbook_options are:
- *
- * - `constant_memory`: Reduces the amount of data stored in memory so that
- *   large files can be written efficiently.
- *
- *   @note In this mode a row of data is written and then discarded when a
- *   cell in a new row is added via one of the `worksheet_write_*()`
- *   functions. Therefore, once this option is active, data should be written in
- *   sequential row order. For this reason the `worksheet_merge_range()`
- *   doesn't work in this mode. See also @ref ww_mem_constant.
- *
- * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior
- *   to assembling the final XLSX file. The temporary files are created in the
- *   system's temp directory. If the default temporary directory isn't
- *   accessible to your application, or doesn't contain enough space, you can
- *   specify an alternative location using the `tempdir` option.*
- *
- * See @ref working_with_memory for more details.
- *
- */
-lxw_workbook *workbook_new_opt(const char *filename,
-                               lxw_workbook_options *options);
-
-/* Deprecated function name for backwards compatibility. */
-lxw_workbook *new_workbook(const char *filename);
-
-/* Deprecated function name for backwards compatibility. */
-lxw_workbook *new_workbook_opt(const char *filename,
-                               lxw_workbook_options *options);
-
-/**
- * @brief Add a new worksheet to a workbook.
- *
- * @param workbook  Pointer to a lxw_workbook instance.
- * @param sheetname Optional worksheet name, defaults to Sheet1, etc.
- *
- * @return A lxw_worksheet object.
- *
- * The `%workbook_add_worksheet()` function adds a new worksheet to a workbook:
- *
- * At least one worksheet should be added to a new workbook: The @ref
- * worksheet.h "Worksheet" object is used to write data and configure a
- * worksheet in the workbook.
- *
- * The `sheetname` parameter is optional. If it is `NULL` the default
- * Excel convention will be followed, i.e. Sheet1, Sheet2, etc.:
- *
- * @code
- *     worksheet = workbook_add_worksheet(workbook, NULL  );     // Sheet1
- *     worksheet = workbook_add_worksheet(workbook, "Foglio2");  // Foglio2
- *     worksheet = workbook_add_worksheet(workbook, "Data");     // Data
- *     worksheet = workbook_add_worksheet(workbook, NULL  );     // Sheet4
- *
- * @endcode
- *
- * @image html workbook02.png
- *
- * The worksheet name must be a valid Excel worksheet name, i.e. it must be
- * less than 32 character and it cannot contain any of the characters:
- *
- *     / \ [ ] : * ?
- *
- * In addition, you cannot use the same, case insensitive, `sheetname` for more
- * than one worksheet.
- *
- */
-lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
-                                      const char *sheetname);
-
-/**
- * @brief Create a new @ref format.h "Format" object to formats cells in
- *        worksheets.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- *
- * @return A lxw_format instance.
- *
- * The `workbook_add_format()` function can be used to create new @ref
- * format.h "Format" objects which are used to apply formatting to a cell.
- *
- * @code
- *    // Create the Format.
- *    lxw_format *format = workbook_add_format(workbook);
- *
- *    // Set some of the format properties.
- *    format_set_bold(format);
- *    format_set_font_color(format, LXW_COLOR_RED);
- *
- *    // Use the format to change the text format in a cell.
- *    worksheet_write_string(worksheet, 0, 0, "Hello", format);
- * @endcode
- *
- * See @ref format.h "the Format object" and @ref working_with_formats
- * sections for more details about Format properties and how to set them.
- *
- */
-lxw_format *workbook_add_format(lxw_workbook *workbook);
-
-/**
- * @brief Create a new chart to be added to a worksheet:
- *
- * @param workbook   Pointer to a lxw_workbook instance.
- * @param chart_type The type of chart to be created. See #lxw_chart_type.
- *
- * @return A lxw_chart object.
- *
- * The `%workbook_add_chart()` function creates a new chart object that can
- * be added to a worksheet:
- *
- * @code
- *     // Create a chart object.
- *     lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
- *
- *     // Add data series to the chart.
- *     chart_add_series(chart, NULL, "Sheet1!$A$1:$A$5");
- *     chart_add_series(chart, NULL, "Sheet1!$B$1:$B$5");
- *     chart_add_series(chart, NULL, "Sheet1!$C$1:$C$5");
- *
- *     // Insert the chart into the worksheet
- *     worksheet_insert_chart(worksheet, CELL("B7"), chart);
- * @endcode
- *
- * The available chart types are defined in #lxw_chart_type. The types of
- * charts that are supported are:
- *
- * | Chart type                               | Description                            |
- * | :--------------------------------------- | :------------------------------------  |
- * | #LXW_CHART_AREA                          | Area chart.                            |
- * | #LXW_CHART_AREA_STACKED                  | Area chart - stacked.                  |
- * | #LXW_CHART_AREA_STACKED_PERCENT          | Area chart - percentage stacked.       |
- * | #LXW_CHART_BAR                           | Bar chart.                             |
- * | #LXW_CHART_BAR_STACKED                   | Bar chart - stacked.                   |
- * | #LXW_CHART_BAR_STACKED_PERCENT           | Bar chart - percentage stacked.        |
- * | #LXW_CHART_COLUMN                        | Column chart.                          |
- * | #LXW_CHART_COLUMN_STACKED                | Column chart - stacked.                |
- * | #LXW_CHART_COLUMN_STACKED_PERCENT        | Column chart - percentage stacked.     |
- * | #LXW_CHART_DOUGHNUT                      | Doughnut chart.                        |
- * | #LXW_CHART_LINE                          | Line chart.                            |
- * | #LXW_CHART_PIE                           | Pie chart.                             |
- * | #LXW_CHART_SCATTER                       | Scatter chart.                         |
- * | #LXW_CHART_SCATTER_STRAIGHT              | Scatter chart - straight.              |
- * | #LXW_CHART_SCATTER_STRAIGHT_WITH_MARKERS | Scatter chart - straight with markers. |
- * | #LXW_CHART_SCATTER_SMOOTH                | Scatter chart - smooth.                |
- * | #LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS   | Scatter chart - smooth with markers.   |
- * | #LXW_CHART_RADAR                         | Radar chart.                           |
- * | #LXW_CHART_RADAR_WITH_MARKERS            | Radar chart - with markers.            |
- * | #LXW_CHART_RADAR_FILLED                  | Radar chart - filled.                  |
- *
- *
- *
- * See @ref chart.h for details.
- */
-lxw_chart *workbook_add_chart(lxw_workbook *workbook, uint8_t chart_type);
-
-/**
- * @brief Close the Workbook object and write the XLSX file.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- *
- * @return A #lxw_error.
- *
- * The `%workbook_close()` function closes a Workbook object, writes the Excel
- * file to disk, frees any memory allocated internally to the Workbook and
- * frees the object itself.
- *
- * @code
- *     workbook_close(workbook);
- * @endcode
- *
- * The `%workbook_close()` function returns any #lxw_error error codes
- * encountered when creating the Excel file. The error code can be returned
- * from the program main or the calling function:
- *
- * @code
- *     return workbook_close(workbook);
- * @endcode
- *
- */
-lxw_error workbook_close(lxw_workbook *workbook);
-
-/**
- * @brief Set the document properties such as Title, Author etc.
- *
- * @param workbook   Pointer to a lxw_workbook instance.
- * @param properties Document properties to set.
- *
- * @return A #lxw_error.
- *
- * The `%workbook_set_properties` function can be used to set the document
- * properties of the Excel file created by `libxlsxwriter`. These properties
- * are visible when you use the `Office Button -> Prepare -> Properties`
- * option in Excel and are also available to external applications that read
- * or index windows files.
- *
- * The properties that can be set are:
- *
- * - `title`
- * - `subject`
- * - `author`
- * - `manager`
- * - `company`
- * - `category`
- * - `keywords`
- * - `comments`
- * - `hyperlink_base`
- *
- * The properties are specified via a `lxw_doc_properties` struct. All the
- * members are `char *` and they are all optional. An example of how to create
- * and pass the properties is:
- *
- * @code
- *     // Create a properties structure and set some of the fields.
- *     lxw_doc_properties properties = {
- *         .title    = "This is an example spreadsheet",
- *         .subject  = "With document properties",
- *         .author   = "John McNamara",
- *         .manager  = "Dr. Heinz Doofenshmirtz",
- *         .company  = "of Wolves",
- *         .category = "Example spreadsheets",
- *         .keywords = "Sample, Example, Properties",
- *         .comments = "Created with libxlsxwriter",
- *         .status   = "Quo",
- *     };
- *
- *     // Set the properties in the workbook.
- *     workbook_set_properties(workbook, &properties);
- * @endcode
- *
- * @image html doc_properties.png
- *
- */
-lxw_error workbook_set_properties(lxw_workbook *workbook,
-                                  lxw_doc_properties *properties);
-
-/**
- * @brief Set a custom document text property.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- * @param name     The name of the custom property.
- * @param value    The value of the custom property.
- *
- * @return A #lxw_error.
- *
- * The `%workbook_set_custom_property_string()` function can be used to set one
- * or more custom document text properties not covered by the standard
- * properties in the `workbook_set_properties()` function above.
- *
- *  For example:
- *
- * @code
- *     workbook_set_custom_property_string(workbook, "Checked by", "Eve");
- * @endcode
- *
- * @image html custom_properties.png
- *
- * There are 4 `workbook_set_custom_property_string_*()` functions for each
- * of the custom property types supported by Excel:
- *
- * - text/string: `workbook_set_custom_property_string()`
- * - number:      `workbook_set_custom_property_number()`
- * - datetime:    `workbook_set_custom_property_datetime()`
- * - boolean:     `workbook_set_custom_property_boolean()`
- *
- * **Note**: the name and value parameters are limited to 255 characters
- * by Excel.
- *
- */
-lxw_error workbook_set_custom_property_string(lxw_workbook *workbook,
-                                              const char *name,
-                                              const char *value);
-/**
- * @brief Set a custom document number property.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- * @param name     The name of the custom property.
- * @param value    The value of the custom property.
- *
- * @return A #lxw_error.
- *
- * Set a custom document number property.
- * See `workbook_set_custom_property_string()` above for details.
- *
- * @code
- *     workbook_set_custom_property_number(workbook, "Document number", 12345);
- * @endcode
- */
-lxw_error workbook_set_custom_property_number(lxw_workbook *workbook,
-                                              const char *name, double value);
-
-/* Undocumented since the user can use workbook_set_custom_property_number().
- * Only implemented for file format completeness and testing.
- */
-lxw_error workbook_set_custom_property_integer(lxw_workbook *workbook,
-                                               const char *name,
-                                               int32_t value);
-
-/**
- * @brief Set a custom document boolean property.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- * @param name     The name of the custom property.
- * @param value    The value of the custom property.
- *
- * @return A #lxw_error.
- *
- * Set a custom document boolean property.
- * See `workbook_set_custom_property_string()` above for details.
- *
- * @code
- *     workbook_set_custom_property_boolean(workbook, "Has Review", 1);
- * @endcode
- */
-lxw_error workbook_set_custom_property_boolean(lxw_workbook *workbook,
-                                               const char *name,
-                                               uint8_t value);
-/**
- * @brief Set a custom document date or time property.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- * @param name     The name of the custom property.
- * @param datetime The value of the custom property.
- *
- * @return A #lxw_error.
- *
- * Set a custom date or time number property.
- * See `workbook_set_custom_property_string()` above for details.
- *
- * @code
- *     lxw_datetime datetime  = {2016, 12, 1,  11, 55, 0.0};
- *
- *     workbook_set_custom_property_datetime(workbook, "Date completed", &datetime);
- * @endcode
- */
-lxw_error workbook_set_custom_property_datetime(lxw_workbook *workbook,
-                                                const char *name,
-                                                lxw_datetime *datetime);
-
-/**
- * @brief Create a defined name in the workbook to use as a variable.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- * @param name     The defined name.
- * @param formula  The cell or range that the defined name refers to.
- *
- * @return A #lxw_error.
- *
- * This function is used to defined a name that can be used to represent a
- * value, a single cell or a range of cells in a workbook: These defined names
- * can then be used in formulas:
- *
- * @code
- *     workbook_define_name(workbook, "Exchange_rate", "=0.96");
- *     worksheet_write_formula(worksheet, 2, 1, "=Exchange_rate", NULL);
- *
- * @endcode
- *
- * @image html defined_name.png
- *
- * As in Excel a name defined like this is "global" to the workbook and can be
- * referred to from any worksheet:
- *
- * @code
- *     // Global workbook name.
- *     workbook_define_name(workbook, "Sales", "=Sheet1!$G$1:$H$10");
- * @endcode
- *
- * It is also possible to define a local/worksheet name by prefixing it with
- * the sheet name using the syntax `'sheetname!definedname'`:
- *
- * @code
- *     // Local worksheet name.
- *     workbook_define_name(workbook, "Sheet2!Sales", "=Sheet2!$G$1:$G$10");
- * @endcode
- *
- * If the sheet name contains spaces or special characters you must follow the
- * Excel convention and enclose it in single quotes:
- *
- * @code
- *     workbook_define_name(workbook, "'New Data'!Sales", "=Sheet2!$G$1:$G$10");
- * @endcode
- *
- * The rules for names in Excel are explained in the
- * [Microsoft Office
-documentation](http://office.microsoft.com/en-001/excel-help/define-and-use-names-in-formulas-HA010147120.aspx).
- *
- */
-lxw_error workbook_define_name(lxw_workbook *workbook, const char *name,
-                               const char *formula);
-
-/**
- * @brief Get a worksheet object from its name.
- *
- * @param workbook Pointer to a lxw_workbook instance.
- * @param name     Worksheet name.
- *
- * @return A lxw_worksheet object.
- *
- * This function returns a lxw_worksheet object reference based on its name:
- *
- * @code
- *     worksheet = workbook_get_worksheet_by_name(workbook, "Sheet1");
- * @endcode
- *
- */
-lxw_worksheet *workbook_get_worksheet_by_name(lxw_workbook *workbook,
-                                              const char *name);
-
-/**
- * @brief Validate a worksheet name.
- *
- * @param workbook  Pointer to a lxw_workbook instance.
- * @param sheetname Worksheet name to validate.
- *
- * @return A #lxw_error.
- *
- * This function is used to validate a worksheet name according to the rules
- * used by Excel:
- *
- * - The name is less than or equal to 31 UTF-8 characters.
- * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
- * - The name isn't already in use.
- *
- * @code
- *     lxw_error err = workbook_validate_worksheet_name(workbook, "Foglio");
- * @endcode
- *
- * This function is called by `workbook_add_worksheet()` but it can be
- * explicitly called by the user beforehand to ensure that the worksheet
- * name is valid.
- *
- */
-lxw_error workbook_validate_worksheet_name(lxw_workbook *workbook,
-                                           const char *sheetname);
-
-void lxw_workbook_free(lxw_workbook *workbook);
-void lxw_workbook_assemble_xml_file(lxw_workbook *workbook);
-void lxw_workbook_set_default_xf_indices(lxw_workbook *workbook);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _workbook_xml_declaration(lxw_workbook *self);
-STATIC void _write_workbook(lxw_workbook *self);
-STATIC void _write_file_version(lxw_workbook *self);
-STATIC void _write_workbook_pr(lxw_workbook *self);
-STATIC void _write_book_views(lxw_workbook *self);
-STATIC void _write_workbook_view(lxw_workbook *self);
-STATIC void _write_sheet(lxw_workbook *self,
-                         const char *name, uint32_t sheet_id, uint8_t hidden);
-STATIC void _write_sheets(lxw_workbook *self);
-STATIC void _write_calc_pr(lxw_workbook *self);
-
-STATIC void _write_defined_name(lxw_workbook *self,
-                                lxw_defined_name *define_name);
-STATIC void _write_defined_names(lxw_workbook *self);
-
-STATIC lxw_error _store_defined_name(lxw_workbook *self, const char *name,
-                                     const char *app_name,
-                                     const char *formula, int16_t index,
-                                     uint8_t hidden);
-
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_WORKBOOK_H__ */

+ 0 - 3119
library/include/xlsxwriter/worksheet.h

@@ -1,3119 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- */
-
-/**
- * @page worksheet_page The Worksheet object
- *
- * The Worksheet object represents an Excel worksheet. It handles
- * operations such as writing data to cells or formatting worksheet
- * layout.
- *
- * See @ref worksheet.h for full details of the functionality.
- *
- * @file worksheet.h
- *
- * @brief Functions related to adding data and formatting to a worksheet.
- *
- * The Worksheet object represents an Excel worksheet. It handles
- * operations such as writing data to cells or formatting worksheet
- * layout.
- *
- * A Worksheet object isn't created directly. Instead a worksheet is
- * created by calling the workbook_add_worksheet() function from a
- * Workbook object:
- *
- * @code
- *     #include "xlsxwriter.h"
- *
- *     int main() {
- *
- *         lxw_workbook  *workbook  = workbook_new("filename.xlsx");
- *         lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
- *
- *         worksheet_write_string(worksheet, 0, 0, "Hello Excel", NULL);
- *
- *         return workbook_close(workbook);
- *     }
- * @endcode
- *
- */
-#ifndef __LXW_WORKSHEET_H__
-#define __LXW_WORKSHEET_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "shared_strings.h"
-#include "chart.h"
-#include "drawing.h"
-#include "common.h"
-#include "format.h"
-#include "utility.h"
-
-#define LXW_ROW_MAX 1048576
-#define LXW_COL_MAX 16384
-#define LXW_COL_META_MAX 128
-#define LXW_HEADER_FOOTER_MAX 255
-#define LXW_MAX_NUMBER_URLS 65530
-#define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
-
-/* The Excel 2007 specification says that the maximum number of page
- * breaks is 1026. However, in practice it is actually 1023. */
-#define LXW_BREAKS_MAX 1023
-
-/** Default column width in Excel */
-#define LXW_DEF_COL_WIDTH (double)8.43
-
-/** Default row height in Excel */
-#define LXW_DEF_ROW_HEIGHT (double)15.0
-
-/** Gridline options using in `worksheet_gridlines()`. */
-enum lxw_gridlines {
-    /** Hide screen and print gridlines. */
-    LXW_HIDE_ALL_GRIDLINES = 0,
-
-    /** Show screen gridlines. */
-    LXW_SHOW_SCREEN_GRIDLINES,
-
-    /** Show print gridlines. */
-    LXW_SHOW_PRINT_GRIDLINES,
-
-    /** Show screen and print gridlines. */
-    LXW_SHOW_ALL_GRIDLINES
-};
-
-/** Data validation property values. */
-enum lxw_validation_boolean {
-    LXW_VALIDATION_DEFAULT,
-
-    /** Turn a data validation property off. */
-    LXW_VALIDATION_OFF,
-
-    /** Turn a data validation property on. Data validation properties are
-     * generally on by default. */
-    LXW_VALIDATION_ON
-};
-
-/** Data validation types. */
-enum lxw_validation_types {
-    LXW_VALIDATION_TYPE_NONE,
-
-    /** Restrict cell input to whole/integer numbers only. */
-    LXW_VALIDATION_TYPE_INTEGER,
-
-    /** Restrict cell input to whole/integer numbers only, using a cell
-     *  reference. */
-    LXW_VALIDATION_TYPE_INTEGER_FORMULA,
-
-    /** Restrict cell input to decimal numbers only. */
-    LXW_VALIDATION_TYPE_DECIMAL,
-
-    /** Restrict cell input to decimal numbers only, using a cell
-     * reference. */
-    LXW_VALIDATION_TYPE_DECIMAL_FORMULA,
-
-    /** Restrict cell input to a list of strings in a dropdown. */
-    LXW_VALIDATION_TYPE_LIST,
-
-    /** Restrict cell input to a list of strings in a dropdown, using a
-     * cell range. */
-    LXW_VALIDATION_TYPE_LIST_FORMULA,
-
-    /** Restrict cell input to date values only, using a lxw_datetime type. */
-    LXW_VALIDATION_TYPE_DATE,
-
-    /** Restrict cell input to date values only, using a cell reference. */
-    LXW_VALIDATION_TYPE_DATE_FORMULA,
-
-    /* Restrict cell input to date values only, as a serial number.
-     * Undocumented. */
-    LXW_VALIDATION_TYPE_DATE_NUMBER,
-
-    /** Restrict cell input to time values only, using a lxw_datetime type. */
-    LXW_VALIDATION_TYPE_TIME,
-
-    /** Restrict cell input to time values only, using a cell reference. */
-    LXW_VALIDATION_TYPE_TIME_FORMULA,
-
-    /* Restrict cell input to time values only, as a serial number.
-     * Undocumented. */
-    LXW_VALIDATION_TYPE_TIME_NUMBER,
-
-    /** Restrict cell input to strings of defined length, using a cell
-     * reference. */
-    LXW_VALIDATION_TYPE_LENGTH,
-
-    /** Restrict cell input to strings of defined length, using a cell
-     * reference. */
-    LXW_VALIDATION_TYPE_LENGTH_FORMULA,
-
-    /** Restrict cell to input controlled by a custom formula that returns
-     * `TRUE/FALSE`. */
-    LXW_VALIDATION_TYPE_CUSTOM_FORMULA,
-
-    /** Allow any type of input. Mainly only useful for pop-up messages. */
-    LXW_VALIDATION_TYPE_ANY
-};
-
-/** Data validation criteria uses to control the selection of data. */
-enum lxw_validation_criteria {
-    LXW_VALIDATION_CRITERIA_NONE,
-
-    /** Select data between two values. */
-    LXW_VALIDATION_CRITERIA_BETWEEN,
-
-    /** Select data that is not between two values. */
-    LXW_VALIDATION_CRITERIA_NOT_BETWEEN,
-
-    /** Select data equal to a value. */
-    LXW_VALIDATION_CRITERIA_EQUAL_TO,
-
-    /** Select data not equal to a value. */
-    LXW_VALIDATION_CRITERIA_NOT_EQUAL_TO,
-
-    /** Select data greater than a value. */
-    LXW_VALIDATION_CRITERIA_GREATER_THAN,
-
-    /** Select data less than a value. */
-    LXW_VALIDATION_CRITERIA_LESS_THAN,
-
-    /** Select data greater than or equal to a value. */
-    LXW_VALIDATION_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
-
-    /** Select data less than or equal to a value. */
-    LXW_VALIDATION_CRITERIA_LESS_THAN_OR_EQUAL_TO
-};
-
-/** Data validation error types for pop-up messages. */
-enum lxw_validation_error_types {
-    /** Show a "Stop" data validation pop-up message. This is the default. */
-    LXW_VALIDATION_ERROR_TYPE_STOP,
-
-    /** Show an "Error" data validation pop-up message. */
-    LXW_VALIDATION_ERROR_TYPE_WARNING,
-
-    /** Show an "Information" data validation pop-up message. */
-    LXW_VALIDATION_ERROR_TYPE_INFORMATION
-};
-
-enum cell_types {
-    NUMBER_CELL = 1,
-    STRING_CELL,
-    INLINE_STRING_CELL,
-    FORMULA_CELL,
-    ARRAY_FORMULA_CELL,
-    BLANK_CELL,
-    BOOLEAN_CELL,
-    HYPERLINK_URL,
-    HYPERLINK_INTERNAL,
-    HYPERLINK_EXTERNAL
-};
-
-enum pane_types {
-    NO_PANES = 0,
-    FREEZE_PANES,
-    SPLIT_PANES,
-    FREEZE_SPLIT_PANES
-};
-
-/* Define the tree.h RB structs for the red-black head types. */
-RB_HEAD(lxw_table_cells, lxw_cell);
-
-/* Define a RB_TREE struct manually to add extra members. */
-struct lxw_table_rows {
-    struct lxw_row *rbh_root;
-    struct lxw_row *cached_row;
-    lxw_row_t cached_row_num;
-};
-
-/* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
- * warnings and to avoid portability issues with the _unused attribute. */
-#define LXW_RB_GENERATE_ROW(name, type, field, cmp)       \
-    RB_GENERATE_INSERT_COLOR(name, type, field, static)   \
-    RB_GENERATE_REMOVE_COLOR(name, type, field, static)   \
-    RB_GENERATE_INSERT(name, type, field, cmp, static)    \
-    RB_GENERATE_REMOVE(name, type, field, static)         \
-    RB_GENERATE_FIND(name, type, field, cmp, static)      \
-    RB_GENERATE_NEXT(name, type, field, static)           \
-    RB_GENERATE_MINMAX(name, type, field, static)         \
-    /* Add unused struct to allow adding a semicolon */   \
-    struct lxw_rb_generate_row{int unused;}
-
-#define LXW_RB_GENERATE_CELL(name, type, field, cmp)      \
-    RB_GENERATE_INSERT_COLOR(name, type, field, static)   \
-    RB_GENERATE_REMOVE_COLOR(name, type, field, static)   \
-    RB_GENERATE_INSERT(name, type, field, cmp, static)    \
-    RB_GENERATE_REMOVE(name, type, field, static)         \
-    RB_GENERATE_FIND(name, type, field, cmp, static)      \
-    RB_GENERATE_NEXT(name, type, field, static)           \
-    RB_GENERATE_MINMAX(name, type, field, static)         \
-    /* Add unused struct to allow adding a semicolon */   \
-    struct lxw_rb_generate_cell{int unused;}
-
-STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
-STAILQ_HEAD(lxw_selections, lxw_selection);
-STAILQ_HEAD(lxw_data_validations, lxw_data_validation);
-STAILQ_HEAD(lxw_image_data, lxw_image_options);
-STAILQ_HEAD(lxw_chart_data, lxw_image_options);
-
-/**
- * @brief Options for rows and columns.
- *
- * Options struct for the worksheet_set_column() and worksheet_set_row()
- * functions.
- *
- * It has the following members:
- *
- * * `hidden`
- * * `level`
- * * `collapsed`
- *
- * The members of this struct are explained in @ref ww_outlines_grouping.
- *
- */
-typedef struct lxw_row_col_options {
-    /** Hide the row/column */
-    uint8_t hidden;
-    uint8_t level;
-    uint8_t collapsed;
-} lxw_row_col_options;
-
-typedef struct lxw_col_options {
-    lxw_col_t firstcol;
-    lxw_col_t lastcol;
-    double width;
-    lxw_format *format;
-    uint8_t hidden;
-    uint8_t level;
-    uint8_t collapsed;
-} lxw_col_options;
-
-typedef struct lxw_merged_range {
-    lxw_row_t first_row;
-    lxw_row_t last_row;
-    lxw_col_t first_col;
-    lxw_col_t last_col;
-
-    STAILQ_ENTRY (lxw_merged_range) list_pointers;
-} lxw_merged_range;
-
-typedef struct lxw_repeat_rows {
-    uint8_t in_use;
-    lxw_row_t first_row;
-    lxw_row_t last_row;
-} lxw_repeat_rows;
-
-typedef struct lxw_repeat_cols {
-    uint8_t in_use;
-    lxw_col_t first_col;
-    lxw_col_t last_col;
-} lxw_repeat_cols;
-
-typedef struct lxw_print_area {
-    uint8_t in_use;
-    lxw_row_t first_row;
-    lxw_row_t last_row;
-    lxw_col_t first_col;
-    lxw_col_t last_col;
-} lxw_print_area;
-
-typedef struct lxw_autofilter {
-    uint8_t in_use;
-    lxw_row_t first_row;
-    lxw_row_t last_row;
-    lxw_col_t first_col;
-    lxw_col_t last_col;
-} lxw_autofilter;
-
-typedef struct lxw_panes {
-    uint8_t type;
-    lxw_row_t first_row;
-    lxw_col_t first_col;
-    lxw_row_t top_row;
-    lxw_col_t left_col;
-    double x_split;
-    double y_split;
-} lxw_panes;
-
-typedef struct lxw_selection {
-    char pane[LXW_PANE_NAME_LENGTH];
-    char active_cell[LXW_MAX_CELL_RANGE_LENGTH];
-    char sqref[LXW_MAX_CELL_RANGE_LENGTH];
-
-    STAILQ_ENTRY (lxw_selection) list_pointers;
-
-} lxw_selection;
-
-/**
- * @brief Worksheet data validation options.
- */
-typedef struct lxw_data_validation {
-
-    /**
-     * Set the validation type. Should be a #lxw_validation_types value.
-     */
-    uint8_t validate;
-
-    /**
-     * Set the validation criteria type to select the data. Should be a
-     * #lxw_validation_criteria value.
-     */
-    uint8_t criteria;
-
-    /** Controls whether a data validation is not applied to blank data in the
-     * cell. Should be a #lxw_validation_boolean value. It is on by
-     * default.
-     */
-    uint8_t ignore_blank;
-
-    /**
-     * This parameter is used to toggle on and off the 'Show input message
-     * when cell is selected' option in the Excel data validation dialog. When
-     * the option is off an input message is not displayed even if it has been
-     * set using input_message. Should be a #lxw_validation_boolean value. It
-     * is on by default.
-     */
-    uint8_t show_input;
-
-    /**
-     * This parameter is used to toggle on and off the 'Show error alert
-     * after invalid data is entered' option in the Excel data validation
-     * dialog. When the option is off an error message is not displayed even
-     * if it has been set using error_message. Should be a
-     * #lxw_validation_boolean value. It is on by default.
-     */
-    uint8_t show_error;
-
-    /**
-     * This parameter is used to specify the type of error dialog that is
-     * displayed. Should be a #lxw_validation_error_types value.
-     */
-    uint8_t error_type;
-
-    /**
-     * This parameter is used to toggle on and off the 'In-cell dropdown'
-     * option in the Excel data validation dialog. When the option is on a
-     * dropdown list will be shown for list validations. Should be a
-     * #lxw_validation_boolean value. It is on by default.
-     */
-    uint8_t dropdown;
-
-    uint8_t is_between;
-
-    /**
-     * This parameter is used to set the limiting value to which the criteria
-     * is applied using a whole or decimal number.
-     */
-    double value_number;
-
-    /**
-     * This parameter is used to set the limiting value to which the criteria
-     * is applied using a cell reference. It is valid for any of the
-     * `_FORMULA` validation types.
-     */
-    char *value_formula;
-
-    /**
-     * This parameter is used to set a list of strings for a drop down list.
-     * The list should be a `NULL` terminated array of char* strings:
-     *
-     * @code
-     *    char *list[] = {"open", "high", "close", NULL};
-     *
-     *    data_validation->validate   = LXW_VALIDATION_TYPE_LIST;
-     *    data_validation->value_list = list;
-     * @endcode
-     *
-     * The `value_formula` parameter can also be used to specify a list from
-     * an Excel cell range.
-     *
-     * Note, the string list is restricted by Excel to 255 characters,
-     * including comma separators.
-     */
-    char **value_list;
-
-    /**
-     * This parameter is used to set the limiting value to which the date or
-     * time criteria is applied using a #lxw_datetime struct.
-     */
-    lxw_datetime value_datetime;
-
-    /**
-     * This parameter is the same as `value_number` but for the minimum value
-     * when a `BETWEEN` criteria is used.
-     */
-    double minimum_number;
-
-    /**
-     * This parameter is the same as `value_formula` but for the minimum value
-     * when a `BETWEEN` criteria is used.
-     */
-    char *minimum_formula;
-
-    /**
-     * This parameter is the same as `value_datetime` but for the minimum value
-     * when a `BETWEEN` criteria is used.
-     */
-    lxw_datetime minimum_datetime;
-
-    /**
-     * This parameter is the same as `value_number` but for the maximum value
-     * when a `BETWEEN` criteria is used.
-     */
-    double maximum_number;
-
-    /**
-     * This parameter is the same as `value_formula` but for the maximum value
-     * when a `BETWEEN` criteria is used.
-     */
-    char *maximum_formula;
-
-    /**
-     * This parameter is the same as `value_datetime` but for the maximum value
-     * when a `BETWEEN` criteria is used.
-     */
-    lxw_datetime maximum_datetime;
-
-    /**
-     * The input_title parameter is used to set the title of the input message
-     * that is displayed when a cell is entered. It has no default value and
-     * is only displayed if the input message is displayed. See the
-     * `input_message` parameter below.
-     *
-     * The maximum title length is 32 characters.
-     */
-    char *input_title;
-
-    /**
-     * The input_message parameter is used to set the input message that is
-     * displayed when a cell is entered. It has no default value.
-     *
-     * The message can be split over several lines using newlines. The maximum
-     * message length is 255 characters.
-     */
-    char *input_message;
-
-    /**
-     * The error_title parameter is used to set the title of the error message
-     * that is displayed when the data validation criteria is not met. The
-     * default error title is 'Microsoft Excel'. The maximum title length is
-     * 32 characters.
-     */
-    char *error_title;
-
-    /**
-     * The error_message parameter is used to set the error message that is
-     * displayed when a cell is entered. The default error message is "The
-     * value you entered is not valid. A user has restricted values that can
-     * be entered into the cell".
-     *
-     * The message can be split over several lines using newlines. The maximum
-     * message length is 255 characters.
-     */
-    char *error_message;
-
-    char sqref[LXW_MAX_CELL_RANGE_LENGTH];
-
-    STAILQ_ENTRY (lxw_data_validation) list_pointers;
-
-} lxw_data_validation;
-
-/**
- * @brief Options for inserted images
- *
- * Options for modifying images inserted via `worksheet_insert_image_opt()`.
- *
- */
-typedef struct lxw_image_options {
-
-    /** Offset from the left of the cell in pixels. */
-    int32_t x_offset;
-
-    /** Offset from the top of the cell in pixels. */
-    int32_t y_offset;
-
-    /** X scale of the image as a decimal. */
-    double x_scale;
-
-    /** Y scale of the image as a decimal. */
-    double y_scale;
-
-    lxw_row_t row;
-    lxw_col_t col;
-    char *filename;
-    char *url;
-    char *tip;
-    uint8_t anchor;
-
-    /* Internal metadata. */
-    FILE *stream;
-    uint8_t image_type;
-    double width;
-    double height;
-    char *short_name;
-    char *extension;
-    double x_dpi;
-    double y_dpi;
-    lxw_chart *chart;
-
-    STAILQ_ENTRY (lxw_image_options) list_pointers;
-
-} lxw_image_options;
-
-/**
- * @brief Header and footer options.
- *
- * Optional parameters used in the worksheet_set_header_opt() and
- * worksheet_set_footer_opt() functions.
- *
- */
-typedef struct lxw_header_footer_options {
-    /** Header or footer margin in inches. Excel default is 0.3. */
-    double margin;
-} lxw_header_footer_options;
-
-/**
- * @brief Worksheet protection options.
- */
-typedef struct lxw_protection {
-    /** Turn off selection of locked cells. This in on in Excel by default.*/
-    uint8_t no_select_locked_cells;
-
-    /** Turn off selection of unlocked cells. This in on in Excel by default.*/
-    uint8_t no_select_unlocked_cells;
-
-    /** Prevent formatting of cells. */
-    uint8_t format_cells;
-
-    /** Prevent formatting of columns. */
-    uint8_t format_columns;
-
-    /** Prevent formatting of rows. */
-    uint8_t format_rows;
-
-    /** Prevent insertion of columns. */
-    uint8_t insert_columns;
-
-    /** Prevent insertion of rows. */
-    uint8_t insert_rows;
-
-    /** Prevent insertion of hyperlinks. */
-    uint8_t insert_hyperlinks;
-
-    /** Prevent deletion of columns. */
-    uint8_t delete_columns;
-
-    /** Prevent deletion of rows. */
-    uint8_t delete_rows;
-
-    /** Prevent sorting data. */
-    uint8_t sort;
-
-    /** Prevent filtering data. */
-    uint8_t autofilter;
-
-    /** Prevent insertion of pivot tables. */
-    uint8_t pivot_tables;
-
-    /** Protect scenarios. */
-    uint8_t scenarios;
-
-    /** Protect drawing objects. */
-    uint8_t objects;
-
-    uint8_t no_sheet;
-    uint8_t content;
-    uint8_t is_configured;
-    char hash[5];
-} lxw_protection;
-
-/**
- * @brief Struct to represent an Excel worksheet.
- *
- * The members of the lxw_worksheet struct aren't modified directly. Instead
- * the worksheet properties are set by calling the functions shown in
- * worksheet.h.
- */
-typedef struct lxw_worksheet {
-
-    FILE *file;
-    FILE *optimize_tmpfile;
-    struct lxw_table_rows *table;
-    struct lxw_table_rows *hyperlinks;
-    struct lxw_cell **array;
-    struct lxw_merged_ranges *merged_ranges;
-    struct lxw_selections *selections;
-    struct lxw_data_validations *data_validations;
-    struct lxw_image_data *image_data;
-    struct lxw_chart_data *chart_data;
-
-    lxw_row_t dim_rowmin;
-    lxw_row_t dim_rowmax;
-    lxw_col_t dim_colmin;
-    lxw_col_t dim_colmax;
-
-    lxw_sst *sst;
-    char *name;
-    char *quoted_name;
-    char *tmpdir;
-
-    uint32_t index;
-    uint8_t active;
-    uint8_t selected;
-    uint8_t hidden;
-    uint16_t *active_sheet;
-    uint16_t *first_sheet;
-
-    lxw_col_options **col_options;
-    uint16_t col_options_max;
-
-    double *col_sizes;
-    uint16_t col_sizes_max;
-
-    lxw_format **col_formats;
-    uint16_t col_formats_max;
-
-    uint8_t col_size_changed;
-    uint8_t row_size_changed;
-    uint8_t optimize;
-    struct lxw_row *optimize_row;
-
-    uint16_t fit_height;
-    uint16_t fit_width;
-    uint16_t horizontal_dpi;
-    uint16_t hlink_count;
-    uint16_t page_start;
-    uint16_t print_scale;
-    uint16_t rel_count;
-    uint16_t vertical_dpi;
-    uint16_t zoom;
-    uint8_t filter_on;
-    uint8_t fit_page;
-    uint8_t hcenter;
-    uint8_t orientation;
-    uint8_t outline_changed;
-    uint8_t outline_on;
-    uint8_t outline_style;
-    uint8_t outline_below;
-    uint8_t outline_right;
-    uint8_t page_order;
-    uint8_t page_setup_changed;
-    uint8_t page_view;
-    uint8_t paper_size;
-    uint8_t print_gridlines;
-    uint8_t print_headers;
-    uint8_t print_options_changed;
-    uint8_t right_to_left;
-    uint8_t screen_gridlines;
-    uint8_t show_zeros;
-    uint8_t vba_codename;
-    uint8_t vcenter;
-    uint8_t zoom_scale_normal;
-    uint8_t num_validations;
-
-    lxw_color_t tab_color;
-
-    double margin_left;
-    double margin_right;
-    double margin_top;
-    double margin_bottom;
-    double margin_header;
-    double margin_footer;
-
-    double default_row_height;
-    uint32_t default_row_pixels;
-    uint32_t default_col_pixels;
-    uint8_t default_row_zeroed;
-    uint8_t default_row_set;
-    uint8_t outline_row_level;
-    uint8_t outline_col_level;
-
-    uint8_t header_footer_changed;
-    char header[LXW_HEADER_FOOTER_MAX];
-    char footer[LXW_HEADER_FOOTER_MAX];
-
-    struct lxw_repeat_rows repeat_rows;
-    struct lxw_repeat_cols repeat_cols;
-    struct lxw_print_area print_area;
-    struct lxw_autofilter autofilter;
-
-    uint16_t merged_range_count;
-
-    lxw_row_t *hbreaks;
-    lxw_col_t *vbreaks;
-    uint16_t hbreaks_count;
-    uint16_t vbreaks_count;
-
-    struct lxw_rel_tuples *external_hyperlinks;
-    struct lxw_rel_tuples *external_drawing_links;
-    struct lxw_rel_tuples *drawing_links;
-
-    struct lxw_panes panes;
-
-    struct lxw_protection protection;
-
-    lxw_drawing *drawing;
-
-    STAILQ_ENTRY (lxw_worksheet) list_pointers;
-
-} lxw_worksheet;
-
-/*
- * Worksheet initialization data.
- */
-typedef struct lxw_worksheet_init_data {
-    uint32_t index;
-    uint8_t hidden;
-    uint8_t optimize;
-    uint16_t *active_sheet;
-    uint16_t *first_sheet;
-    lxw_sst *sst;
-    char *name;
-    char *quoted_name;
-    char *tmpdir;
-
-} lxw_worksheet_init_data;
-
-/* Struct to represent a worksheet row. */
-typedef struct lxw_row {
-    lxw_row_t row_num;
-    double height;
-    lxw_format *format;
-    uint8_t hidden;
-    uint8_t level;
-    uint8_t collapsed;
-    uint8_t row_changed;
-    uint8_t data_changed;
-    uint8_t height_changed;
-    struct lxw_table_cells *cells;
-
-    /* tree management pointers for tree.h. */
-    RB_ENTRY (lxw_row) tree_pointers;
-} lxw_row;
-
-/* Struct to represent a worksheet cell. */
-typedef struct lxw_cell {
-    lxw_row_t row_num;
-    lxw_col_t col_num;
-    enum cell_types type;
-    lxw_format *format;
-
-    union {
-        double number;
-        int32_t string_id;
-        char *string;
-    } u;
-
-    double formula_result;
-    char *user_data1;
-    char *user_data2;
-    char *sst_string;
-
-    /* List pointers for tree.h. */
-    RB_ENTRY (lxw_cell) tree_pointers;
-} lxw_cell;
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-/**
- * @brief Write a number to a worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param number    The number to write to the cell.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * The `worksheet_write_number()` function writes numeric types to the cell
- * specified by `row` and `column`:
- *
- * @code
- *     worksheet_write_number(worksheet, 0, 0, 123456, NULL);
- *     worksheet_write_number(worksheet, 1, 0, 2.3451, NULL);
- * @endcode
- *
- * @image html write_number01.png
- *
- * The native data type for all numbers in Excel is a IEEE-754 64-bit
- * double-precision floating point, which is also the default type used by
- * `%worksheet_write_number`.
- *
- * The `format` parameter is used to apply formatting to the cell. This
- * parameter can be `NULL` to indicate no formatting or it can be a
- * @ref format.h "Format" object.
- *
- * @code
- *     lxw_format *format = workbook_add_format(workbook);
- *     format_set_num_format(format, "$#,##0.00");
- *
- *     worksheet_write_number(worksheet, 0, 0, 1234.567, format);
- * @endcode
- *
- * @image html write_number02.png
- *
- * @note Excel doesn't support `NaN`, `Inf` or `-Inf` as a number value. If
- * you are writing data that contains these values then your application
- * should convert them to a string or handle them in some other way.
- *
- */
-lxw_error worksheet_write_number(lxw_worksheet *worksheet,
-                                 lxw_row_t row,
-                                 lxw_col_t col, double number,
-                                 lxw_format *format);
-/**
- * @brief Write a string to a worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param string    String to write to cell.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_write_string()` function writes a string to the cell
- * specified by `row` and `column`:
- *
- * @code
- *     worksheet_write_string(worksheet, 0, 0, "This phrase is English!", NULL);
- * @endcode
- *
- * @image html write_string01.png
- *
- * The `format` parameter is used to apply formatting to the cell. This
- * parameter can be `NULL` to indicate no formatting or it can be a
- * @ref format.h "Format" object:
- *
- * @code
- *     lxw_format *format = workbook_add_format(workbook);
- *     format_set_bold(format);
- *
- *     worksheet_write_string(worksheet, 0, 0, "This phrase is Bold!", format);
- * @endcode
- *
- * @image html write_string02.png
- *
- * Unicode strings are supported in UTF-8 encoding. This generally requires
- * that your source file is UTF-8 encoded or that the data has been read from
- * a UTF-8 source:
- *
- * @code
- *    worksheet_write_string(worksheet, 0, 0, "Это фраза на русском!", NULL);
- * @endcode
- *
- * @image html write_string03.png
- *
- */
-lxw_error worksheet_write_string(lxw_worksheet *worksheet,
-                                 lxw_row_t row,
-                                 lxw_col_t col, const char *string,
-                                 lxw_format *format);
-/**
- * @brief Write a formula to a worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param formula   Formula string to write to cell.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_write_formula()` function writes a formula or function to
- * the cell specified by `row` and `column`:
- *
- * @code
- *  worksheet_write_formula(worksheet, 0, 0, "=B3 + 6",                    NULL);
- *  worksheet_write_formula(worksheet, 1, 0, "=SIN(PI()/4)",               NULL);
- *  worksheet_write_formula(worksheet, 2, 0, "=SUM(A1:A2)",                NULL);
- *  worksheet_write_formula(worksheet, 3, 0, "=IF(A3>1,\"Yes\", \"No\")",  NULL);
- *  worksheet_write_formula(worksheet, 4, 0, "=AVERAGE(1, 2, 3, 4)",       NULL);
- *  worksheet_write_formula(worksheet, 5, 0, "=DATEVALUE(\"1-Jan-2013\")", NULL);
- * @endcode
- *
- * @image html write_formula01.png
- *
- * The `format` parameter is used to apply formatting to the cell. This
- * parameter can be `NULL` to indicate no formatting or it can be a
- * @ref format.h "Format" object.
- *
- * Libxlsxwriter doesn't calculate the value of a formula and instead stores a
- * default value of `0`. The correct formula result is displayed in Excel, as
- * shown in the example above, since it recalculates the formulas when it loads
- * the file. For cases where this is an issue see the
- * `worksheet_write_formula_num()` function and the discussion in that section.
- *
- * Formulas must be written with the US style separator/range operator which
- * is a comma (not semi-colon). Therefore a formula with multiple values
- * should be written as follows:
- *
- * @code
- *     // OK.
- *     worksheet_write_formula(worksheet, 0, 0, "=SUM(1, 2, 3)", NULL);
- *
- *     // NO. Error on load.
- *     worksheet_write_formula(worksheet, 1, 0, "=SUM(1; 2; 3)", NULL);
- * @endcode
- *
- * See also @ref working_with_formulas.
- */
-lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
-                                  lxw_row_t row,
-                                  lxw_col_t col, const char *formula,
-                                  lxw_format *format);
-/**
- * @brief Write an array formula to a worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param first_row   The first row of the range. (All zero indexed.)
- * @param first_col   The first column of the range.
- * @param last_row    The last row of the range.
- * @param last_col    The last col of the range.
- * @param formula     Array formula to write to cell.
- * @param format      A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
-  * The `%worksheet_write_array_formula()` function writes an array formula to
- * a cell range. In Excel an array formula is a formula that performs a
- * calculation on a set of values.
- *
- * In Excel an array formula is indicated by a pair of braces around the
- * formula: `{=SUM(A1:B1*A2:B2)}`.
- *
- * Array formulas can return a single value or a range or values. For array
- * formulas that return a range of values you must specify the range that the
- * return values will be written to. This is why this function has `first_`
- * and `last_` row/column parameters. The RANGE() macro can also be used to
- * specify the range:
- *
- * @code
- *     worksheet_write_array_formula(worksheet, 4, 0, 6, 0,     "{=TREND(C5:C7,B5:B7)}", NULL);
- *
- *     // Same as above using the RANGE() macro.
- *     worksheet_write_array_formula(worksheet, RANGE("A5:A7"), "{=TREND(C5:C7,B5:B7)}", NULL);
- * @endcode
- *
- * If the array formula returns a single value then the `first_` and `last_`
- * parameters should be the same:
- *
- * @code
- *     worksheet_write_array_formula(worksheet, 1, 0, 1, 0,     "{=SUM(B1:C1*B2:C2)}", NULL);
- *     worksheet_write_array_formula(worksheet, RANGE("A2:A2"), "{=SUM(B1:C1*B2:C2)}", NULL);
- * @endcode
- *
- */
-lxw_error worksheet_write_array_formula(lxw_worksheet *worksheet,
-                                        lxw_row_t first_row,
-                                        lxw_col_t first_col,
-                                        lxw_row_t last_row,
-                                        lxw_col_t last_col,
-                                        const char *formula,
-                                        lxw_format *format);
-
-lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
-                                            lxw_row_t first_row,
-                                            lxw_col_t first_col,
-                                            lxw_row_t last_row,
-                                            lxw_col_t last_col,
-                                            const char *formula,
-                                            lxw_format *format,
-                                            double result);
-
-/**
- * @brief Write a date or time to a worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param datetime  The datetime to write to the cell.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * The `worksheet_write_datetime()` function can be used to write a date or
- * time to the cell specified by `row` and `column`:
- *
- * @dontinclude dates_and_times02.c
- * @skip include
- * @until num_format
- * @skip Feb
- * @until }
- *
- * The `format` parameter should be used to apply formatting to the cell using
- * a @ref format.h "Format" object as shown above. Without a date format the
- * datetime will appear as a number only.
- *
- * See @ref working_with_dates for more information about handling dates and
- * times in libxlsxwriter.
- */
-lxw_error worksheet_write_datetime(lxw_worksheet *worksheet,
-                                   lxw_row_t row,
-                                   lxw_col_t col, lxw_datetime *datetime,
-                                   lxw_format *format);
-
-lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
-                                  lxw_row_t row_num,
-                                  lxw_col_t col_num, const char *url,
-                                  lxw_format *format, const char *string,
-                                  const char *tooltip);
-/**
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param url       The url to write to the cell.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- *
- * The `%worksheet_write_url()` function is used to write a URL/hyperlink to a
- * worksheet cell specified by `row` and `column`.
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", url_format);
- * @endcode
- *
- * @image html hyperlinks_short.png
- *
- * The `format` parameter is used to apply formatting to the cell. This
- * parameter can be `NULL` to indicate no formatting or it can be a @ref
- * format.h "Format" object. The typical worksheet format for a hyperlink is a
- * blue underline:
- *
- * @code
- *    lxw_format *url_format   = workbook_add_format(workbook);
- *
- *    format_set_underline (url_format, LXW_UNDERLINE_SINGLE);
- *    format_set_font_color(url_format, LXW_COLOR_BLUE);
- *
- * @endcode
- *
- * The usual web style URI's are supported: `%http://`, `%https://`, `%ftp://`
- * and `mailto:` :
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/",     url_format);
- *     worksheet_write_url(worksheet, 1, 0, "http://www.python.org/",    url_format);
- *     worksheet_write_url(worksheet, 2, 0, "https://www.python.org/",   url_format);
- *     worksheet_write_url(worksheet, 3, 0, "mailto:[email protected]", url_format);
- *
- * @endcode
- *
- * An Excel hyperlink is comprised of two elements: the displayed string and
- * the non-displayed link. By default the displayed string is the same as the
- * link. However, it is possible to overwrite it with any other
- * `libxlsxwriter` type using the appropriate `worksheet_write_*()`
- * function. The most common case is to overwrite the displayed link text with
- * another string:
- *
- * @code
- *  // Write a hyperlink but overwrite the displayed string.
- *  worksheet_write_url   (worksheet, 2, 0, "http://libxlsxwriter.github.io", url_format);
- *  worksheet_write_string(worksheet, 2, 0, "Read the documentation.",        url_format);
- *
- * @endcode
- *
- * @image html hyperlinks_short2.png
- *
- * Two local URIs are supported: `internal:` and `external:`. These are used
- * for hyperlinks to internal worksheet references or external workbook and
- * worksheet references:
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1",                url_format);
- *     worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2",                url_format);
- *     worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2",             url_format);
- *     worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1",          url_format);
- *     worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx",       url_format);
- *     worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1",   url_format);
- *     worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx",             url_format);
- *     worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1",   url_format);
- *     worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
- *
- * @endcode
- *
- * Worksheet references are typically of the form `Sheet1!A1`. You can also
- * link to a worksheet range using the standard Excel notation:
- * `Sheet1!A1:B2`.
- *
- * In external links the workbook and worksheet name must be separated by the
- * `#` character:
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1",   url_format);
- * @endcode
- *
- * You can also link to a named range in the target worksheet: For example say
- * you have a named range called `my_name` in the workbook `c:\temp\foo.xlsx`
- * you could link to it as follows:
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", url_format);
- *
- * @endcode
- *
- * Excel requires that worksheet names containing spaces or non alphanumeric
- * characters are single quoted as follows:
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", url_format);
- * @endcode
- *
- * Links to network files are also supported. Network files normally begin
- * with two back slashes as follows `\\NETWORK\etc`. In order to represent
- * this in a C string literal the backslashes should be escaped:
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
- * @endcode
- *
- *
- * Alternatively, you can use Unix style forward slashes. These are
- * translated internally to backslashes:
- *
- * @code
- *     worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx",     url_format);
- *     worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", url_format);
- *
- * @endcode
- *
- *
- * **Note:**
- *
- *    libxlsxwriter will escape the following characters in URLs as required
- *    by Excel: `\s " < > \ [ ]  ^ { }` unless the URL already contains `%%xx`
- *    style escapes. In which case it is assumed that the URL was escaped
- *    correctly by the user and will by passed directly to Excel.
- *
- */
-lxw_error worksheet_write_url(lxw_worksheet *worksheet,
-                              lxw_row_t row,
-                              lxw_col_t col, const char *url,
-                              lxw_format *format);
-
-/**
- * @brief Write a formatted boolean worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param value     The boolean value to write to the cell.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * Write an Excel boolean to the cell specified by `row` and `column`:
- *
- * @code
- *     worksheet_write_boolean(worksheet, 2, 2, 0, my_format);
- * @endcode
- *
- */
-lxw_error worksheet_write_boolean(lxw_worksheet *worksheet,
-                                  lxw_row_t row, lxw_col_t col,
-                                  int value, lxw_format *format);
-
-/**
- * @brief Write a formatted blank worksheet cell.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * Write a blank cell specified by `row` and `column`:
- *
- * @code
- *     worksheet_write_blank(worksheet, 1, 1, border_format);
- * @endcode
- *
- * This function is used to add formatting to a cell which doesn't contain a
- * string or number value.
- *
- * Excel differentiates between an "Empty" cell and a "Blank" cell. An Empty
- * cell is a cell which doesn't contain data or formatting whilst a Blank cell
- * doesn't contain data but does contain formatting. Excel stores Blank cells
- * but ignores Empty cells.
- *
- * As such, if you write an empty cell without formatting it is ignored.
- *
- */
-lxw_error worksheet_write_blank(lxw_worksheet *worksheet,
-                                lxw_row_t row, lxw_col_t col,
-                                lxw_format *format);
-
-/**
- * @brief Write a formula to a worksheet cell with a user defined result.
- *
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param formula   Formula string to write to cell.
- * @param format    A pointer to a Format instance or NULL.
- * @param result    A user defined result for a formula.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_write_formula_num()` function writes a formula or Excel
- * function to the cell specified by `row` and `column` with a user defined
- * result:
- *
- * @code
- *     // Required as a workaround only.
- *     worksheet_write_formula_num(worksheet, 0, 0, "=1 + 2", NULL, 3);
- * @endcode
- *
- * Libxlsxwriter doesn't calculate the value of a formula and instead stores
- * the value `0` as the formula result. It then sets a global flag in the XLSX
- * file to say that all formulas and functions should be recalculated when the
- * file is opened.
- *
- * This is the method recommended in the Excel documentation and in general it
- * works fine with spreadsheet applications.
- *
- * However, applications that don't have a facility to calculate formulas,
- * such as Excel Viewer, or some mobile applications will only display the `0`
- * results.
- *
- * If required, the `%worksheet_write_formula_num()` function can be used to
- * specify a formula and its result.
- *
- * This function is rarely required and is only provided for compatibility
- * with some third party applications. For most applications the
- * worksheet_write_formula() function is the recommended way of writing
- * formulas.
- *
- * See also @ref working_with_formulas.
- */
-lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
-                                      lxw_row_t row,
-                                      lxw_col_t col,
-                                      const char *formula,
-                                      lxw_format *format, double result);
-
-/**
- * @brief Set the properties for a row of cells.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param height    The row height.
- * @param format    A pointer to a Format instance or NULL.
- *
- * The `%worksheet_set_row()` function is used to change the default
- * properties of a row. The most common use for this function is to change the
- * height of a row:
- *
- * @code
- *     // Set the height of Row 1 to 20.
- *     worksheet_set_row(worksheet, 0, 20, NULL);
- * @endcode
- *
- * The other common use for `%worksheet_set_row()` is to set the a @ref
- * format.h "Format" for all cells in the row:
- *
- * @code
- *     lxw_format *bold = workbook_add_format(workbook);
- *     format_set_bold(bold);
- *
- *     // Set the header row to bold.
- *     worksheet_set_row(worksheet, 0, 15, bold);
- * @endcode
- *
- * If you wish to set the format of a row without changing the height you can
- * pass the default row height of #LXW_DEF_ROW_HEIGHT = 15:
- *
- * @code
- *     worksheet_set_row(worksheet, 0, LXW_DEF_ROW_HEIGHT, format);
- *     worksheet_set_row(worksheet, 0, 15, format); // Same as above.
- * @endcode
- *
- * The `format` parameter will be applied to any cells in the row that don't
- * have a format. As with Excel the row format is overridden by an explicit
- * cell format. For example:
- *
- * @code
- *     // Row 1 has format1.
- *     worksheet_set_row(worksheet, 0, 15, format1);
- *
- *     // Cell A1 in Row 1 defaults to format1.
- *     worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
- *
- *     // Cell B1 in Row 1 keeps format2.
- *     worksheet_write_string(worksheet, 0, 1, "Hello", format2);
- * @endcode
- *
- */
-lxw_error worksheet_set_row(lxw_worksheet *worksheet,
-                            lxw_row_t row, double height, lxw_format *format);
-
-/**
- * @brief Set the properties for a row of cells.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param height    The row height.
- * @param format    A pointer to a Format instance or NULL.
- * @param options   Optional row parameters: hidden, level, collapsed.
- *
- * The `%worksheet_set_row_opt()` function  is the same as
- *  `worksheet_set_row()` with an additional `options` parameter.
- *
- * The `options` parameter is a #lxw_row_col_options struct. It has the
- * following members:
- *
- * - `hidden`
- * - `level`
- * - `collapsed`
- *
- * The `"hidden"` option is used to hide a row. This can be used, for
- * example, to hide intermediary steps in a complicated calculation:
- *
- * @code
- *     lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
- *
- *     // Hide the fourth and fifth (zero indexed) rows.
- *     worksheet_set_row_opt(worksheet, 3,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 4,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *
- * @endcode
- *
- * @image html hide_row_col2.png
- *
- * The `"hidden"`, `"level"`,  and `"collapsed"`, options can also be used to
- * create Outlines and Grouping. See @ref working_with_outlines.
- *
- * @code
- *     // The option structs with the outline level set.
- *     lxw_row_col_options options1 = {.hidden = 0, .level = 2, .collapsed = 0};
- *     lxw_row_col_options options2 = {.hidden = 0, .level = 1, .collapsed = 0};
- *
- *
- *     // Set the row options with the outline level.
- *     worksheet_set_row_opt(worksheet, 1,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 2,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 3,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 4,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 5,  LXW_DEF_ROW_HEIGHT, NULL, &options2);
- *
- *     worksheet_set_row_opt(worksheet, 6,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 7,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 8,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 9,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
- *     worksheet_set_row_opt(worksheet, 10, LXW_DEF_ROW_HEIGHT, NULL, &options2);
- * @endcode
- *
- * @image html outline1.png
- *
- */
-lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
-                                lxw_row_t row,
-                                double height,
-                                lxw_format *format,
-                                lxw_row_col_options *options);
-
-/**
- * @brief Set the properties for one or more columns of cells.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_col The zero indexed first column.
- * @param last_col  The zero indexed last column.
- * @param width     The width of the column(s).
- * @param format    A pointer to a Format instance or NULL.
- *
- * The `%worksheet_set_column()` function can be used to change the default
- * properties of a single column or a range of columns:
- *
- * @code
- *     // Width of columns B:D set to 30.
- *     worksheet_set_column(worksheet, 1, 3, 30, NULL);
- *
- * @endcode
- *
- * If `%worksheet_set_column()` is applied to a single column the value of
- * `first_col` and `last_col` should be the same:
- *
- * @code
- *     // Width of column B set to 30.
- *     worksheet_set_column(worksheet, 1, 1, 30, NULL);
- *
- * @endcode
- *
- * It is also possible, and generally clearer, to specify a column range using
- * the form of `COLS()` macro:
- *
- * @code
- *     worksheet_set_column(worksheet, 4, 4, 20, NULL);
- *     worksheet_set_column(worksheet, 5, 8, 30, NULL);
- *
- *     // Same as the examples above but clearer.
- *     worksheet_set_column(worksheet, COLS("E:E"), 20, NULL);
- *     worksheet_set_column(worksheet, COLS("F:H"), 30, NULL);
- *
- * @endcode
- *
- * The `width` parameter sets the column width in the same units used by Excel
- * which is: the number of characters in the default font. The default width
- * is 8.43 in the default font of Calibri 11. The actual relationship between
- * a string width and a column width in Excel is complex. See the
- * [following explanation of column widths](https://support.microsoft.com/en-us/kb/214123)
- * from the Microsoft support documentation for more details.
- *
- * There is no way to specify "AutoFit" for a column in the Excel file
- * format. This feature is only available at runtime from within Excel. It is
- * possible to simulate "AutoFit" in your application by tracking the maximum
- * width of the data in the column as your write it and then adjusting the
- * column width at the end.
- *
- * As usual the @ref format.h `format` parameter is optional. If you wish to
- * set the format without changing the width you can pass a default column
- * width of #LXW_DEF_COL_WIDTH = 8.43:
- *
- * @code
- *     lxw_format *bold = workbook_add_format(workbook);
- *     format_set_bold(bold);
- *
- *     // Set the first column to bold.
- *     worksheet_set_column(worksheet, 0, 0, LXW_DEF_COL_HEIGHT, bold);
- * @endcode
- *
- * The `format` parameter will be applied to any cells in the column that
- * don't have a format. For example:
- *
- * @code
- *     // Column 1 has format1.
- *     worksheet_set_column(worksheet, COLS("A:A"), 8.43, format1);
- *
- *     // Cell A1 in column 1 defaults to format1.
- *     worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
- *
- *     // Cell A2 in column 1 keeps format2.
- *     worksheet_write_string(worksheet, 1, 0, "Hello", format2);
- * @endcode
- *
- * As in Excel a row format takes precedence over a default column format:
- *
- * @code
- *     // Row 1 has format1.
- *     worksheet_set_row(worksheet, 0, 15, format1);
- *
- *     // Col 1 has format2.
- *     worksheet_set_column(worksheet, COLS("A:A"), 8.43, format2);
- *
- *     // Cell A1 defaults to format1, the row format.
- *     worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
- *
- *    // Cell A2 keeps format2, the column format.
- *     worksheet_write_string(worksheet, 1, 0, "Hello", NULL);
- * @endcode
- */
-lxw_error worksheet_set_column(lxw_worksheet *worksheet,
-                               lxw_col_t first_col,
-                               lxw_col_t last_col,
-                               double width, lxw_format *format);
-
-/**
- * @brief Set the properties for one or more columns of cells with options.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_col The zero indexed first column.
- * @param last_col  The zero indexed last column.
- * @param width     The width of the column(s).
- * @param format    A pointer to a Format instance or NULL.
- * @param options   Optional row parameters: hidden, level, collapsed.
- *
- * The `%worksheet_set_column_opt()` function  is the same as
- * `worksheet_set_column()` with an additional `options` parameter.
- *
- * The `options` parameter is a #lxw_row_col_options struct. It has the
- * following members:
- *
- * - `hidden`
- * - `level`
- * - `collapsed`
- *
- * The `"hidden"` option is used to hide a column. This can be used, for
- * example, to hide intermediary steps in a complicated calculation:
- *
- * @code
- *     lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
- *
- *     worksheet_set_column_opt(worksheet, COLS("D:E"),  LXW_DEF_COL_WIDTH, NULL, &options1);
- * @endcode
- *
- * @image html hide_row_col3.png
- *
- * The `"hidden"`, `"level"`,  and `"collapsed"`, options can also be used to
- * create Outlines and Grouping. See @ref working_with_outlines.
- *
- * @code
- *     lxw_row_col_options options1 = {.hidden = 0, .level = 1, .collapsed = 0};
- *
- *     worksheet_set_column_opt(worksheet, COLS("B:G"),  5, NULL, &options1);
- * @endcode
- *
- * @image html outline8.png
- */
-lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
-                                   lxw_col_t first_col,
-                                   lxw_col_t last_col,
-                                   double width,
-                                   lxw_format *format,
-                                   lxw_row_col_options *options);
-
-/**
- * @brief Insert an image in a worksheet cell.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param filename  The image filename, with path if required.
- *
- * @return A #lxw_error code.
- *
- * This function can be used to insert a image into a worksheet. The image can
- * be in PNG, JPEG or BMP format:
- *
- * @code
- *     worksheet_insert_image(worksheet, 2, 1, "logo.png");
- * @endcode
- *
- * @image html insert_image.png
- *
- * The `worksheet_insert_image_opt()` function takes additional optional
- * parameters to position and scale the image, see below.
- *
- * **Note**:
- * The scaling of a image may be affected if is crosses a row that has its
- * default height changed due to a font that is larger than the default font
- * size or that has text wrapping turned on. To avoid this you should
- * explicitly set the height of the row using `worksheet_set_row()` if it
- * crosses an inserted image.
- *
- * BMP images are only supported for backward compatibility. In general it is
- * best to avoid BMP images since they aren't compressed. If used, BMP images
- * must be 24 bit, true color, bitmaps.
- */
-lxw_error worksheet_insert_image(lxw_worksheet *worksheet,
-                                 lxw_row_t row, lxw_col_t col,
-                                 const char *filename);
-
-/**
- * @brief Insert an image in a worksheet cell, with options.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param filename  The image filename, with path if required.
- * @param options   Optional image parameters.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_insert_image_opt()` function is like
- * `worksheet_insert_image()` function except that it takes an optional
- * #lxw_image_options struct to scale and position the image:
- *
- * @code
- *    lxw_image_options options = {.x_offset = 30,  .y_offset = 10,
- *                                 .x_scale  = 0.5, .y_scale  = 0.5};
- *
- *    worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
- *
- * @endcode
- *
- * @image html insert_image_opt.png
- *
- * @note See the notes about row scaling and BMP images in
- * `worksheet_insert_image()` above.
- */
-lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
-                                     lxw_row_t row, lxw_col_t col,
-                                     const char *filename,
-                                     lxw_image_options *options);
-/**
- * @brief Insert a chart object into a worksheet.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param row       The zero indexed row number.
- * @param col       The zero indexed column number.
- * @param chart     A #lxw_chart object created via workbook_add_chart().
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_insert_chart()` can be used to insert a chart into a
- * worksheet. The chart object must be created first using the
- * `workbook_add_chart()` function and configured using the @ref chart.h
- * functions.
- *
- * @code
- *     // Create a chart object.
- *     lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
- *
- *     // Add a data series to the chart.
- *     chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$6");
- *
- *     // Insert the chart into the worksheet
- *     worksheet_insert_chart(worksheet, 0, 2, chart);
- * @endcode
- *
- * @image html chart_working.png
- *
- *
- * **Note:**
- *
- * A chart may only be inserted into a worksheet once. If several similar
- * charts are required then each one must be created separately with
- * `%worksheet_insert_chart()`.
- *
- */
-lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
-                                 lxw_row_t row, lxw_col_t col,
-                                 lxw_chart *chart);
-
-/**
- * @brief Insert a chart object into a worksheet, with options.
- *
- * @param worksheet    Pointer to a lxw_worksheet instance to be updated.
- * @param row          The zero indexed row number.
- * @param col          The zero indexed column number.
- * @param chart        A #lxw_chart object created via workbook_add_chart().
- * @param user_options Optional chart parameters.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_insert_chart_opt()` function is like
- * `worksheet_insert_chart()` function except that it takes an optional
- * #lxw_image_options struct to scale and position the image of the chart:
- *
- * @code
- *    lxw_image_options options = {.x_offset = 30,  .y_offset = 10,
- *                                 .x_scale  = 0.5, .y_scale  = 0.75};
- *
- *    worksheet_insert_chart_opt(worksheet, 0, 2, chart, &options);
- *
- * @endcode
- *
- * @image html chart_line_opt.png
- *
- * The #lxw_image_options struct is the same struct used in
- * `worksheet_insert_image_opt()` to position and scale images.
- *
- */
-lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
-                                     lxw_row_t row, lxw_col_t col,
-                                     lxw_chart *chart,
-                                     lxw_image_options *user_options);
-
-/**
- * @brief Merge a range of cells.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_row The first row of the range. (All zero indexed.)
- * @param first_col The first column of the range.
- * @param last_row  The last row of the range.
- * @param last_col  The last col of the range.
- * @param string    String to write to the merged range.
- * @param format    A pointer to a Format instance or NULL.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_merge_range()` function allows cells to be merged together
- * so that they act as a single area.
- *
- * Excel generally merges and centers cells at same time. To get similar
- * behavior with libxlsxwriter you need to apply a @ref format.h "Format"
- * object with the appropriate alignment:
- *
- * @code
- *     lxw_format *merge_format = workbook_add_format(workbook);
- *     format_set_align(merge_format, LXW_ALIGN_CENTER);
- *
- *     worksheet_merge_range(worksheet, 1, 1, 1, 3, "Merged Range", merge_format);
- *
- * @endcode
- *
- * It is possible to apply other formatting to the merged cells as well:
- *
- * @code
- *    format_set_align   (merge_format, LXW_ALIGN_CENTER);
- *    format_set_align   (merge_format, LXW_ALIGN_VERTICAL_CENTER);
- *    format_set_border  (merge_format, LXW_BORDER_DOUBLE);
- *    format_set_bold    (merge_format);
- *    format_set_bg_color(merge_format, 0xD7E4BC);
- *
- *    worksheet_merge_range(worksheet, 2, 1, 3, 3, "Merged Range", merge_format);
- *
- * @endcode
- *
- * @image html merge.png
- *
- * The `%worksheet_merge_range()` function writes a `char*` string using
- * `worksheet_write_string()`. In order to write other data types, such as a
- * number or a formula, you can overwrite the first cell with a call to one of
- * the other write functions. The same Format should be used as was used in
- * the merged range.
- *
- * @code
- *    // First write a range with a blank string.
- *    worksheet_merge_range (worksheet, 1, 1, 1, 3, "", format);
- *
- *    // Then overwrite the first cell with a number.
- *    worksheet_write_number(worksheet, 1, 1, 123, format);
- * @endcode
- *
- * @note Merged ranges generally don’t work in libxlsxwriter when the Workbook
- * #lxw_workbook_options `constant_memory` mode is enabled.
- */
-lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
-                                lxw_col_t first_col, lxw_row_t last_row,
-                                lxw_col_t last_col, const char *string,
-                                lxw_format *format);
-
-/**
- * @brief Set the autofilter area in the worksheet.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_row The first row of the range. (All zero indexed.)
- * @param first_col The first column of the range.
- * @param last_row  The last row of the range.
- * @param last_col  The last col of the range.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_autofilter()` function allows an autofilter to be added to
- * a worksheet.
- *
- * An autofilter is a way of adding drop down lists to the headers of a 2D
- * range of worksheet data. This allows users to filter the data based on
- * simple criteria so that some data is shown and some is hidden.
- *
- * @image html autofilter.png
- *
- * To add an autofilter to a worksheet:
- *
- * @code
- *     worksheet_autofilter(worksheet, 0, 0, 50, 3);
- *
- *     // Same as above using the RANGE() macro.
- *     worksheet_autofilter(worksheet, RANGE("A1:D51"));
- * @endcode
- *
- * Note: it isn't currently possible to apply filter conditions to the
- * autofilter.
- */
-lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row,
-                               lxw_col_t first_col, lxw_row_t last_row,
-                               lxw_col_t last_col);
-
-/**
- * @brief Add a data validation to a cell.
- *
- * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
- * @param row        The zero indexed row number.
- * @param col        The zero indexed column number.
- * @param validation A #lxw_data_validation object to control the validation.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_data_validation_cell()` function is used to construct an
- * Excel data validation or to limit the user input to a dropdown list of
- * values:
- *
- * @code
- *
- *    lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
- *
- *    data_validation->validate       = LXW_VALIDATION_TYPE_INTEGER;
- *    data_validation->criteria       = LXW_VALIDATION_CRITERIA_BETWEEN;
- *    data_validation->minimum_number = 1;
- *    data_validation->maximum_number = 10;
- *
- *    worksheet_data_validation_cell(worksheet, 2, 1, data_validation);
- *
- *    // Same as above with the CELL() macro.
- *    worksheet_data_validation_cell(worksheet, CELL("B3"), data_validation);
- *
- * @endcode
- *
- * @image html data_validate4.png
- *
- * Data validation and the various options of #lxw_data_validation are
- * described in more detail in @ref working_with_data_validation.
- */
-lxw_error worksheet_data_validation_cell(lxw_worksheet *worksheet,
-                                         lxw_row_t row, lxw_col_t col,
-                                         lxw_data_validation *validation);
-
-/**
- * @brief Add a data validation to a range cell.
- *
- * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
- * @param first_row  The first row of the range. (All zero indexed.)
- * @param first_col  The first column of the range.
- * @param last_row   The last row of the range.
- * @param last_col   The last col of the range.
- * @param validation A #lxw_data_validation object to control the validation.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_data_validation_range()` function is the same as the
- * `%worksheet_data_validation_cell()`, see above,  except the data validation
- * is applied to a range of cells:
- *
- * @code
- *
- *    lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
- *
- *    data_validation->validate       = LXW_VALIDATION_TYPE_INTEGER;
- *    data_validation->criteria       = LXW_VALIDATION_CRITERIA_BETWEEN;
- *    data_validation->minimum_number = 1;
- *    data_validation->maximum_number = 10;
- *
- *    worksheet_data_validation_range(worksheet, 2, 1, 4, 1, data_validation);
- *
- *    // Same as above with the RANGE() macro.
- *    worksheet_data_validation_range(worksheet, RANGE("B3:B5"), data_validation);
- *
- * @endcode
- *
- * Data validation and the various options of #lxw_data_validation are
- * described in more detail in @ref working_with_data_validation.
- */
-lxw_error worksheet_data_validation_range(lxw_worksheet *worksheet,
-                                          lxw_row_t first_row,
-                                          lxw_col_t first_col,
-                                          lxw_row_t last_row,
-                                          lxw_col_t last_col,
-                                          lxw_data_validation *validation);
-
- /**
-  * @brief Make a worksheet the active, i.e., visible worksheet.
-  *
-  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
-  *
-  * The `%worksheet_activate()` function is used to specify which worksheet is
-  * initially visible in a multi-sheet workbook:
-  *
-  * @code
-  *     lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL);
-  *     lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL);
-  *     lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, NULL);
-  *
-  *     worksheet_activate(worksheet3);
-  * @endcode
-  *
-  * @image html worksheet_activate.png
-  *
-  * More than one worksheet can be selected via the `worksheet_select()`
-  * function, see below, however only one worksheet can be active.
-  *
-  * The default active worksheet is the first worksheet.
-  *
-  */
-void worksheet_activate(lxw_worksheet *worksheet);
-
- /**
-  * @brief Set a worksheet tab as selected.
-  *
-  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
-  *
-  * The `%worksheet_select()` function is used to indicate that a worksheet is
-  * selected in a multi-sheet workbook:
-  *
-  * @code
-  *     worksheet_activate(worksheet1);
-  *     worksheet_select(worksheet2);
-  *     worksheet_select(worksheet3);
-  *
-  * @endcode
-  *
-  * A selected worksheet has its tab highlighted. Selecting worksheets is a
-  * way of grouping them together so that, for example, several worksheets
-  * could be printed in one go. A worksheet that has been activated via the
-  * `worksheet_activate()` function will also appear as selected.
-  *
-  */
-void worksheet_select(lxw_worksheet *worksheet);
-
-/**
- * @brief Hide the current worksheet.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * The `%worksheet_hide()` function is used to hide a worksheet:
- *
- * @code
- *     worksheet_hide(worksheet2);
- * @endcode
- *
- * You may wish to hide a worksheet in order to avoid confusing a user with
- * intermediate data or calculations.
- *
- * @image html hide_sheet.png
- *
- * A hidden worksheet can not be activated or selected so this function is
- * mutually exclusive with the `worksheet_activate()` and `worksheet_select()`
- * functions. In addition, since the first worksheet will default to being the
- * active worksheet, you cannot hide the first worksheet without activating
- * another sheet:
- *
- * @code
- *     worksheet_activate(worksheet2);
- *     worksheet_hide(worksheet1);
- * @endcode
- */
-void worksheet_hide(lxw_worksheet *worksheet);
-
-/**
- * @brief Set current worksheet as the first visible sheet tab.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * The `worksheet_activate()` function determines which worksheet is initially
- * selected.  However, if there are a large number of worksheets the selected
- * worksheet may not appear on the screen. To avoid this you can select the
- * leftmost visible worksheet tab using `%worksheet_set_first_sheet()`:
- *
- * @code
- *     worksheet_set_first_sheet(worksheet19); // First visible worksheet tab.
- *     worksheet_activate(worksheet20);        // First visible worksheet.
- * @endcode
- *
- * This function is not required very often. The default value is the first
- * worksheet.
- */
-void worksheet_set_first_sheet(lxw_worksheet *worksheet);
-
-/**
- * @brief Split and freeze a worksheet into panes.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param row       The cell row (zero indexed).
- * @param col       The cell column (zero indexed).
- *
- * The `%worksheet_freeze_panes()` function can be used to divide a worksheet
- * into horizontal or vertical regions known as panes and to "freeze" these
- * panes so that the splitter bars are not visible.
- *
- * The parameters `row` and `col` are used to specify the location of the
- * split. It should be noted that the split is specified at the top or left of
- * a cell and that the function uses zero based indexing. Therefore to freeze
- * the first row of a worksheet it is necessary to specify the split at row 2
- * (which is 1 as the zero-based index).
- *
- * You can set one of the `row` and `col` parameters as zero if you do not
- * want either a vertical or horizontal split.
- *
- * Examples:
- *
- * @code
- *     worksheet_freeze_panes(worksheet1, 1, 0); // Freeze the first row.
- *     worksheet_freeze_panes(worksheet2, 0, 1); // Freeze the first column.
- *     worksheet_freeze_panes(worksheet3, 1, 1); // Freeze first row/column.
- *
- * @endcode
- *
- */
-void worksheet_freeze_panes(lxw_worksheet *worksheet,
-                            lxw_row_t row, lxw_col_t col);
-/**
- * @brief Split a worksheet into panes.
- *
- * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
- * @param vertical   The position for the vertical split.
- * @param horizontal The position for the horizontal split.
- *
- * The `%worksheet_split_panes()` function can be used to divide a worksheet
- * into horizontal or vertical regions known as panes. This function is
- * different from the `worksheet_freeze_panes()` function in that the splits
- * between the panes will be visible to the user and each pane will have its
- * own scroll bars.
- *
- * The parameters `vertical` and `horizontal` are used to specify the vertical
- * and horizontal position of the split. The units for `vertical` and
- * `horizontal` are the same as those used by Excel to specify row height and
- * column width. However, the vertical and horizontal units are different from
- * each other. Therefore you must specify the `vertical` and `horizontal`
- * parameters in terms of the row heights and column widths that you have set
- * or the default values which are 15 for a row and 8.43 for a column.
- *
- * Examples:
- *
- * @code
- *     worksheet_split_panes(worksheet1, 15, 0);    // First row.
- *     worksheet_split_panes(worksheet2, 0,  8.43); // First column.
- *     worksheet_split_panes(worksheet3, 15, 8.43); // First row and column.
- *
- * @endcode
- *
- */
-void worksheet_split_panes(lxw_worksheet *worksheet,
-                           double vertical, double horizontal);
-
-/* worksheet_freeze_panes() with infrequent options. Undocumented for now. */
-void worksheet_freeze_panes_opt(lxw_worksheet *worksheet,
-                                lxw_row_t first_row, lxw_col_t first_col,
-                                lxw_row_t top_row, lxw_col_t left_col,
-                                uint8_t type);
-
-/* worksheet_split_panes() with infrequent options. Undocumented for now. */
-void worksheet_split_panes_opt(lxw_worksheet *worksheet,
-                               double vertical, double horizontal,
-                               lxw_row_t top_row, lxw_col_t left_col);
-/**
- * @brief Set the selected cell or cells in a worksheet:
- *
- * @param worksheet   Pointer to a lxw_worksheet instance to be updated.
- * @param first_row   The first row of the range. (All zero indexed.)
- * @param first_col   The first column of the range.
- * @param last_row    The last row of the range.
- * @param last_col    The last col of the range.
- *
- *
- * The `%worksheet_set_selection()` function can be used to specify which cell
- * or range of cells is selected in a worksheet: The most common requirement
- * is to select a single cell, in which case the `first_` and `last_`
- * parameters should be the same.
- *
- * The active cell within a selected range is determined by the order in which
- * `first_` and `last_` are specified.
- *
- * Examples:
- *
- * @code
- *     worksheet_set_selection(worksheet1, 3, 3, 3, 3);     // Cell D4.
- *     worksheet_set_selection(worksheet2, 3, 3, 6, 6);     // Cells D4 to G7.
- *     worksheet_set_selection(worksheet3, 6, 6, 3, 3);     // Cells G7 to D4.
- *     worksheet_set_selection(worksheet5, RANGE("D4:G7")); // Using the RANGE macro.
- *
- * @endcode
- *
- */
-void worksheet_set_selection(lxw_worksheet *worksheet,
-                             lxw_row_t first_row, lxw_col_t first_col,
-                             lxw_row_t last_row, lxw_col_t last_col);
-
-/**
- * @brief Set the page orientation as landscape.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * This function is used to set the orientation of a worksheet's printed page
- * to landscape:
- *
- * @code
- *     worksheet_set_landscape(worksheet);
- * @endcode
- */
-void worksheet_set_landscape(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the page orientation as portrait.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * This function is used to set the orientation of a worksheet's printed page
- * to portrait. The default worksheet orientation is portrait, so this
- * function isn't generally required:
- *
- * @code
- *     worksheet_set_portrait(worksheet);
- * @endcode
- */
-void worksheet_set_portrait(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the page layout to page view mode.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * This function is used to display the worksheet in "Page View/Layout" mode:
- *
- * @code
- *     worksheet_set_page_view(worksheet);
- * @endcode
- */
-void worksheet_set_page_view(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the paper type for printing.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param paper_type The Excel paper format type.
- *
- * This function is used to set the paper format for the printed output of a
- * worksheet. The following paper styles are available:
- *
- *
- *   Index    | Paper format            | Paper size
- *   :------- | :---------------------- | :-------------------
- *   0        | Printer default         | Printer default
- *   1        | Letter                  | 8 1/2 x 11 in
- *   2        | Letter Small            | 8 1/2 x 11 in
- *   3        | Tabloid                 | 11 x 17 in
- *   4        | Ledger                  | 17 x 11 in
- *   5        | Legal                   | 8 1/2 x 14 in
- *   6        | Statement               | 5 1/2 x 8 1/2 in
- *   7        | Executive               | 7 1/4 x 10 1/2 in
- *   8        | A3                      | 297 x 420 mm
- *   9        | A4                      | 210 x 297 mm
- *   10       | A4 Small                | 210 x 297 mm
- *   11       | A5                      | 148 x 210 mm
- *   12       | B4                      | 250 x 354 mm
- *   13       | B5                      | 182 x 257 mm
- *   14       | Folio                   | 8 1/2 x 13 in
- *   15       | Quarto                  | 215 x 275 mm
- *   16       | ---                     | 10x14 in
- *   17       | ---                     | 11x17 in
- *   18       | Note                    | 8 1/2 x 11 in
- *   19       | Envelope 9              | 3 7/8 x 8 7/8
- *   20       | Envelope 10             | 4 1/8 x 9 1/2
- *   21       | Envelope 11             | 4 1/2 x 10 3/8
- *   22       | Envelope 12             | 4 3/4 x 11
- *   23       | Envelope 14             | 5 x 11 1/2
- *   24       | C size sheet            | ---
- *   25       | D size sheet            | ---
- *   26       | E size sheet            | ---
- *   27       | Envelope DL             | 110 x 220 mm
- *   28       | Envelope C3             | 324 x 458 mm
- *   29       | Envelope C4             | 229 x 324 mm
- *   30       | Envelope C5             | 162 x 229 mm
- *   31       | Envelope C6             | 114 x 162 mm
- *   32       | Envelope C65            | 114 x 229 mm
- *   33       | Envelope B4             | 250 x 353 mm
- *   34       | Envelope B5             | 176 x 250 mm
- *   35       | Envelope B6             | 176 x 125 mm
- *   36       | Envelope                | 110 x 230 mm
- *   37       | Monarch                 | 3.875 x 7.5 in
- *   38       | Envelope                | 3 5/8 x 6 1/2 in
- *   39       | Fanfold                 | 14 7/8 x 11 in
- *   40       | German Std Fanfold      | 8 1/2 x 12 in
- *   41       | German Legal Fanfold    | 8 1/2 x 13 in
- *
- * Note, it is likely that not all of these paper types will be available to
- * the end user since it will depend on the paper formats that the user's
- * printer supports. Therefore, it is best to stick to standard paper types:
- *
- * @code
- *     worksheet_set_paper(worksheet1, 1);  // US Letter
- *     worksheet_set_paper(worksheet2, 9);  // A4
- * @endcode
- *
- * If you do not specify a paper type the worksheet will print using the
- * printer's default paper style.
- */
-void worksheet_set_paper(lxw_worksheet *worksheet, uint8_t paper_type);
-
-/**
- * @brief Set the worksheet margins for the printed page.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param left    Left margin in inches.   Excel default is 0.7.
- * @param right   Right margin in inches.  Excel default is 0.7.
- * @param top     Top margin in inches.    Excel default is 0.75.
- * @param bottom  Bottom margin in inches. Excel default is 0.75.
- *
- * The `%worksheet_set_margins()` function is used to set the margins of the
- * worksheet when it is printed. The units are in inches. Specifying `-1` for
- * any parameter will give the default Excel value as shown above.
- *
- * @code
- *    worksheet_set_margins(worksheet, 1.3, 1.2, -1, -1);
- * @endcode
- *
- */
-void worksheet_set_margins(lxw_worksheet *worksheet, double left,
-                           double right, double top, double bottom);
-
-/**
- * @brief Set the printed page header caption.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param string    The header string.
- *
- * @return A #lxw_error code.
- *
- * Headers and footers are generated using a string which is a combination of
- * plain text and control characters.
- *
- * The available control character are:
- *
- *
- *   | Control         | Category      | Description           |
- *   | --------------- | ------------- | --------------------- |
- *   | `&L`            | Justification | Left                  |
- *   | `&C`            |               | Center                |
- *   | `&R`            |               | Right                 |
- *   | `&P`            | Information   | Page number           |
- *   | `&N`            |               | Total number of pages |
- *   | `&D`            |               | Date                  |
- *   | `&T`            |               | Time                  |
- *   | `&F`            |               | File name             |
- *   | `&A`            |               | Worksheet name        |
- *   | `&Z`            |               | Workbook path         |
- *   | `&fontsize`     | Font          | Font size             |
- *   | `&"font,style"` |               | Font name and style   |
- *   | `&U`            |               | Single underline      |
- *   | `&E`            |               | Double underline      |
- *   | `&S`            |               | Strikethrough         |
- *   | `&X`            |               | Superscript           |
- *   | `&Y`            |               | Subscript             |
- *
- *
- * Text in headers and footers can be justified (aligned) to the left, center
- * and right by prefixing the text with the control characters `&L`, `&C` and
- * `&R`.
- *
- * For example (with ASCII art representation of the results):
- *
- * @code
- *     worksheet_set_header(worksheet, "&LHello");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     | Hello                                                         |
- *     |                                                               |
- *
- *
- *     worksheet_set_header(worksheet, "&CHello");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     |                          Hello                                |
- *     |                                                               |
- *
- *
- *     worksheet_set_header(worksheet, "&RHello");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     |                                                         Hello |
- *     |                                                               |
- *
- *
- * @endcode
- *
- * For simple text, if you do not specify any justification the text will be
- * centered. However, you must prefix the text with `&C` if you specify a font
- * name or any other formatting:
- *
- * @code
- *     worksheet_set_header(worksheet, "Hello");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     |                          Hello                                |
- *     |                                                               |
- *
- * @endcode
- *
- * You can have text in each of the justification regions:
- *
- * @code
- *     worksheet_set_header(worksheet, "&LCiao&CBello&RCielo");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     | Ciao                     Bello                          Cielo |
- *     |                                                               |
- *
- * @endcode
- *
- * The information control characters act as variables that Excel will update
- * as the workbook or worksheet changes. Times and dates are in the users
- * default format:
- *
- * @code
- *     worksheet_set_header(worksheet, "&CPage &P of &N");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     |                        Page 1 of 6                            |
- *     |                                                               |
- *
- *     worksheet_set_header(worksheet, "&CUpdated at &T");
- *
- *      ---------------------------------------------------------------
- *     |                                                               |
- *     |                    Updated at 12:30 PM                        |
- *     |                                                               |
- *
- * @endcode
- *
- * You can specify the font size of a section of the text by prefixing it with
- * the control character `&n` where `n` is the font size:
- *
- * @code
- *     worksheet_set_header(worksheet1, "&C&30Hello Big");
- *     worksheet_set_header(worksheet2, "&C&10Hello Small");
- *
- * @endcode
- *
- * You can specify the font of a section of the text by prefixing it with the
- * control sequence `&"font,style"` where `fontname` is a font name such as
- * Windows font descriptions: "Regular", "Italic", "Bold" or "Bold Italic":
- * "Courier New" or "Times New Roman" and `style` is one of the standard
- *
- * @code
- *     worksheet_set_header(worksheet1, "&C&\"Courier New,Italic\"Hello");
- *     worksheet_set_header(worksheet2, "&C&\"Courier New,Bold Italic\"Hello");
- *     worksheet_set_header(worksheet3, "&C&\"Times New Roman,Regular\"Hello");
- *
- * @endcode
- *
- * It is possible to combine all of these features together to create
- * sophisticated headers and footers. As an aid to setting up complicated
- * headers and footers you can record a page set-up as a macro in Excel and
- * look at the format strings that VBA produces. Remember however that VBA
- * uses two double quotes `""` to indicate a single double quote. For the last
- * example above the equivalent VBA code looks like this:
- *
- * @code
- *     .LeftHeader = ""
- *     .CenterHeader = "&""Times New Roman,Regular""Hello"
- *     .RightHeader = ""
- *
- * @endcode
- *
- * Alternatively you can inspect the header and footer strings in an Excel
- * file by unzipping it and grepping the XML sub-files. The following shows
- * how to do that using libxml's xmllint to format the XML for clarity:
- *
- * @code
- *
- *    $ unzip myfile.xlsm -d myfile
- *    $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer"
- *
- *      <headerFooter scaleWithDoc="0">
- *        <oddHeader>&amp;L&amp;P</oddHeader>
- *      </headerFooter>
- *
- * @endcode
- *
- * Note that in this case you need to unescape the Html. In the above example
- * the header string would be `&L&P`.
- *
- * To include a single literal ampersand `&` in a header or footer you should
- * use a double ampersand `&&`:
- *
- * @code
- *     worksheet_set_header(worksheet, "&CCuriouser && Curiouser - Attorneys at Law");
- * @endcode
- *
- * Note, the header or footer string must be less than 255 characters. Strings
- * longer than this will not be written.
- *
- */
-lxw_error worksheet_set_header(lxw_worksheet *worksheet, const char *string);
-
-/**
- * @brief Set the printed page footer caption.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param string    The footer string.
- *
- * @return A #lxw_error code.
- *
- * The syntax of this function is the same as worksheet_set_header().
- *
- */
-lxw_error worksheet_set_footer(lxw_worksheet *worksheet, const char *string);
-
-/**
- * @brief Set the printed page header caption with additional options.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param string    The header string.
- * @param options   Header options.
- *
- * @return A #lxw_error code.
- *
- * The syntax of this function is the same as worksheet_set_header() with an
- * additional parameter to specify options for the header.
- *
- * Currently, the only available option is the header margin:
- *
- * @code
- *
- *    lxw_header_footer_options header_options = { 0.2 };
- *
- *    worksheet_set_header_opt(worksheet, "Some text", &header_options);
- *
- * @endcode
- *
- */
-lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
-                                   const char *string,
-                                   lxw_header_footer_options *options);
-
-/**
- * @brief Set the printed page footer caption with additional options.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param string    The footer string.
- * @param options   Footer options.
- *
- * @return A #lxw_error code.
- *
- * The syntax of this function is the same as worksheet_set_header_opt().
- *
- */
-lxw_error worksheet_set_footer_opt(lxw_worksheet *worksheet,
-                                   const char *string,
-                                   lxw_header_footer_options *options);
-
-/**
- * @brief Set the horizontal page breaks on a worksheet.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param breaks    Array of page breaks.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_set_h_pagebreaks()` function adds horizontal page breaks to
- * a worksheet. A page break causes all the data that follows it to be printed
- * on the next page. Horizontal page breaks act between rows.
- *
- * The function takes an array of one or more page breaks. The type of the
- * array data is @ref lxw_row_t and the last element of the array must be 0:
- *
- * @code
- *    lxw_row_t breaks1[] = {20, 0}; // 1 page break. Zero indicates the end.
- *    lxw_row_t breaks2[] = {20, 40, 60, 80, 0};
- *
- *    worksheet_set_h_pagebreaks(worksheet1, breaks1);
- *    worksheet_set_h_pagebreaks(worksheet2, breaks2);
- * @endcode
- *
- * To create a page break between rows 20 and 21 you must specify the break at
- * row 21. However in zero index notation this is actually row 20:
- *
- * @code
- *    // Break between row 20 and 21.
- *    lxw_row_t breaks[] = {20, 0};
- *
- *    worksheet_set_h_pagebreaks(worksheet, breaks);
- * @endcode
- *
- * There is an Excel limitation of 1023 horizontal page breaks per worksheet.
- *
- * Note: If you specify the "fit to page" option via the
- * `worksheet_fit_to_pages()` function it will override all manual page
- * breaks.
- *
- */
-lxw_error worksheet_set_h_pagebreaks(lxw_worksheet *worksheet,
-                                     lxw_row_t breaks[]);
-
-/**
- * @brief Set the vertical page breaks on a worksheet.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param breaks    Array of page breaks.
- *
- * @return A #lxw_error code.
- *
- * The `%worksheet_set_v_pagebreaks()` function adds vertical page breaks to a
- * worksheet. A page break causes all the data that follows it to be printed
- * on the next page. Vertical page breaks act between columns.
- *
- * The function takes an array of one or more page breaks. The type of the
- * array data is @ref lxw_col_t and the last element of the array must be 0:
- *
- * @code
- *    lxw_col_t breaks1[] = {20, 0}; // 1 page break. Zero indicates the end.
- *    lxw_col_t breaks2[] = {20, 40, 60, 80, 0};
- *
- *    worksheet_set_v_pagebreaks(worksheet1, breaks1);
- *    worksheet_set_v_pagebreaks(worksheet2, breaks2);
- * @endcode
- *
- * To create a page break between columns 20 and 21 you must specify the break
- * at column 21. However in zero index notation this is actually column 20:
- *
- * @code
- *    // Break between column 20 and 21.
- *    lxw_col_t breaks[] = {20, 0};
- *
- *    worksheet_set_v_pagebreaks(worksheet, breaks);
- * @endcode
- *
- * There is an Excel limitation of 1023 vertical page breaks per worksheet.
- *
- * Note: If you specify the "fit to page" option via the
- * `worksheet_fit_to_pages()` function it will override all manual page
- * breaks.
- *
- */
-lxw_error worksheet_set_v_pagebreaks(lxw_worksheet *worksheet,
-                                     lxw_col_t breaks[]);
-
-/**
- * @brief Set the order in which pages are printed.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * The `%worksheet_print_across()` function is used to change the default
- * print direction. This is referred to by Excel as the sheet "page order":
- *
- * @code
- *     worksheet_print_across(worksheet);
- * @endcode
- *
- * The default page order is shown below for a worksheet that extends over 4
- * pages. The order is called "down then across":
- *
- *     [1] [3]
- *     [2] [4]
- *
- * However, by using the `print_across` function the print order will be
- * changed to "across then down":
- *
- *     [1] [2]
- *     [3] [4]
- *
- */
-void worksheet_print_across(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the worksheet zoom factor.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param scale     Worksheet zoom factor.
- *
- * Set the worksheet zoom factor in the range `10 <= zoom <= 400`:
- *
- * @code
- *     worksheet_set_zoom(worksheet1, 50);
- *     worksheet_set_zoom(worksheet2, 75);
- *     worksheet_set_zoom(worksheet3, 300);
- *     worksheet_set_zoom(worksheet4, 400);
- * @endcode
- *
- * The default zoom factor is 100. It isn't possible to set the zoom to
- * "Selection" because it is calculated by Excel at run-time.
- *
- * Note, `%worksheet_zoom()` does not affect the scale of the printed
- * page. For that you should use `worksheet_set_print_scale()`.
- */
-void worksheet_set_zoom(lxw_worksheet *worksheet, uint16_t scale);
-
-/**
- * @brief Set the option to display or hide gridlines on the screen and
- *        the printed page.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param option    Gridline option.
- *
- * Display or hide screen and print gridlines using one of the values of
- * @ref lxw_gridlines.
- *
- * @code
- *    worksheet_gridlines(worksheet1, LXW_HIDE_ALL_GRIDLINES);
- *
- *    worksheet_gridlines(worksheet2, LXW_SHOW_PRINT_GRIDLINES);
- * @endcode
- *
- * The Excel default is that the screen gridlines are on  and the printed
- * worksheet is off.
- *
- */
-void worksheet_gridlines(lxw_worksheet *worksheet, uint8_t option);
-
-/**
- * @brief Center the printed page horizontally.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * Center the worksheet data horizontally between the margins on the printed
- * page:
- *
- * @code
- *     worksheet_center_horizontally(worksheet);
- * @endcode
- *
- */
-void worksheet_center_horizontally(lxw_worksheet *worksheet);
-
-/**
- * @brief Center the printed page vertically.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * Center the worksheet data vertically between the margins on the printed
- * page:
- *
- * @code
- *     worksheet_center_vertically(worksheet);
- * @endcode
- *
- */
-void worksheet_center_vertically(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the option to print the row and column headers on the printed
- *        page.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * When printing a worksheet from Excel the row and column headers (the row
- * numbers on the left and the column letters at the top) aren't printed by
- * default.
- *
- * This function sets the printer option to print these headers:
- *
- * @code
- *    worksheet_print_row_col_headers(worksheet);
- * @endcode
- *
- */
-void worksheet_print_row_col_headers(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the number of rows to repeat at the top of each printed page.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_row First row of repeat range.
- * @param last_row  Last row of repeat range.
- *
- * @return A #lxw_error code.
- *
- * For large Excel documents it is often desirable to have the first row or
- * rows of the worksheet print out at the top of each page.
- *
- * This can be achieved by using this function. The parameters `first_row`
- * and `last_row` are zero based:
- *
- * @code
- *     worksheet_repeat_rows(worksheet, 0, 0); // Repeat the first row.
- *     worksheet_repeat_rows(worksheet, 0, 1); // Repeat the first two rows.
- * @endcode
- */
-lxw_error worksheet_repeat_rows(lxw_worksheet *worksheet, lxw_row_t first_row,
-                                lxw_row_t last_row);
-
-/**
- * @brief Set the number of columns to repeat at the top of each printed page.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_col First column of repeat range.
- * @param last_col  Last column of repeat range.
- *
- * @return A #lxw_error code.
- *
- * For large Excel documents it is often desirable to have the first column or
- * columns of the worksheet print out at the left of each page.
- *
- * This can be achieved by using this function. The parameters `first_col`
- * and `last_col` are zero based:
- *
- * @code
- *     worksheet_repeat_columns(worksheet, 0, 0); // Repeat the first col.
- *     worksheet_repeat_columns(worksheet, 0, 1); // Repeat the first two cols.
- * @endcode
- */
-lxw_error worksheet_repeat_columns(lxw_worksheet *worksheet,
-                                   lxw_col_t first_col, lxw_col_t last_col);
-
-/**
- * @brief Set the print area for a worksheet.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param first_row The first row of the range. (All zero indexed.)
- * @param first_col The first column of the range.
- * @param last_row  The last row of the range.
- * @param last_col  The last col of the range.
- *
- * @return A #lxw_error code.
- *
- * This function is used to specify the area of the worksheet that will be
- * printed. The RANGE() macro is often convenient for this.
- *
- * @code
- *     worksheet_print_area(worksheet, 0, 0, 41, 10); // A1:K42.
- *
- *     // Same as:
- *     worksheet_print_area(worksheet, RANGE("A1:K42"));
- * @endcode
- *
- * In order to set a row or column range you must specify the entire range:
- *
- * @code
- *     worksheet_print_area(worksheet, RANGE("A1:H1048576")); // Same as A:H.
- * @endcode
- */
-lxw_error worksheet_print_area(lxw_worksheet *worksheet, lxw_row_t first_row,
-                               lxw_col_t first_col, lxw_row_t last_row,
-                               lxw_col_t last_col);
-/**
- * @brief Fit the printed area to a specific number of pages both vertically
- *        and horizontally.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param width     Number of pages horizontally.
- * @param height    Number of pages vertically.
- *
- * The `%worksheet_fit_to_pages()` function is used to fit the printed area to
- * a specific number of pages both vertically and horizontally. If the printed
- * area exceeds the specified number of pages it will be scaled down to
- * fit. This ensures that the printed area will always appear on the specified
- * number of pages even if the page size or margins change:
- *
- * @code
- *     worksheet_fit_to_pages(worksheet1, 1, 1); // Fit to 1x1 pages.
- *     worksheet_fit_to_pages(worksheet2, 2, 1); // Fit to 2x1 pages.
- *     worksheet_fit_to_pages(worksheet3, 1, 2); // Fit to 1x2 pages.
- * @endcode
- *
- * The print area can be defined using the `worksheet_print_area()` function
- * as described above.
- *
- * A common requirement is to fit the printed output to `n` pages wide but
- * have the height be as long as necessary. To achieve this set the `height`
- * to zero:
- *
- * @code
- *     // 1 page wide and as long as necessary.
- *     worksheet_fit_to_pages(worksheet, 1, 0);
- * @endcode
- *
- * **Note**:
- *
- * - Although it is valid to use both `%worksheet_fit_to_pages()` and
- *   `worksheet_set_print_scale()` on the same worksheet Excel only allows one
- *   of these options to be active at a time. The last function call made will
- *   set the active option.
- *
- * - The `%worksheet_fit_to_pages()` function will override any manual page
- *   breaks that are defined in the worksheet.
- *
- * - When using `%worksheet_fit_to_pages()` it may also be required to set the
- *   printer paper size using `worksheet_set_paper()` or else Excel will
- *   default to "US Letter".
- *
- */
-void worksheet_fit_to_pages(lxw_worksheet *worksheet, uint16_t width,
-                            uint16_t height);
-
-/**
- * @brief Set the start page number when printing.
- *
- * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
- * @param start_page Starting page number.
- *
- * The `%worksheet_set_start_page()` function is used to set the number of
- * the starting page when the worksheet is printed out:
- *
- * @code
- *     // Start print from page 2.
- *     worksheet_set_start_page(worksheet, 2);
- * @endcode
- */
-void worksheet_set_start_page(lxw_worksheet *worksheet, uint16_t start_page);
-
-/**
- * @brief Set the scale factor for the printed page.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param scale     Print scale of worksheet to be printed.
- *
- * This function sets the scale factor of the printed page. The Scale factor
- * must be in the range `10 <= scale <= 400`:
- *
- * @code
- *     worksheet_set_print_scale(worksheet1, 75);
- *     worksheet_set_print_scale(worksheet2, 400);
- * @endcode
- *
- * The default scale factor is 100. Note, `%worksheet_set_print_scale()` does
- * not affect the scale of the visible page in Excel. For that you should use
- * `worksheet_set_zoom()`.
- *
- * Note that although it is valid to use both `worksheet_fit_to_pages()` and
- * `%worksheet_set_print_scale()` on the same worksheet Excel only allows one
- * of these options to be active at a time. The last function call made will
- * set the active option.
- *
- */
-void worksheet_set_print_scale(lxw_worksheet *worksheet, uint16_t scale);
-
-/**
- * @brief Display the worksheet cells from right to left for some versions of
- *        Excel.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
-  * The `%worksheet_right_to_left()` function is used to change the default
- * direction of the worksheet from left-to-right, with the `A1` cell in the
- * top left, to right-to-left, with the `A1` cell in the top right.
- *
- * @code
- *     worksheet_right_to_left(worksheet1);
- * @endcode
- *
- * This is useful when creating Arabic, Hebrew or other near or far eastern
- * worksheets that use right-to-left as the default direction.
- */
-void worksheet_right_to_left(lxw_worksheet *worksheet);
-
-/**
- * @brief Hide zero values in worksheet cells.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- *
- * The `%worksheet_hide_zero()` function is used to hide any zero values that
- * appear in cells:
- *
- * @code
- *     worksheet_hide_zero(worksheet1);
- * @endcode
- */
-void worksheet_hide_zero(lxw_worksheet *worksheet);
-
-/**
- * @brief Set the color of the worksheet tab.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param color     The tab color.
- *
- * The `%worksheet_set_tab_color()` function is used to change the color of the worksheet
- * tab:
- *
- * @code
- *      worksheet_set_tab_color(worksheet1, LXW_COLOR_RED);
- *      worksheet_set_tab_color(worksheet2, LXW_COLOR_GREEN);
- *      worksheet_set_tab_color(worksheet3, 0xFF9900); // Orange.
- * @endcode
- *
- * The color should be an RGB integer value, see @ref working_with_colors.
- */
-void worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
-
-/**
- * @brief Protect elements of a worksheet from modification.
- *
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param password  A worksheet password.
- * @param options   Worksheet elements to protect.
- *
- * The `%worksheet_protect()` function protects worksheet elements from modification:
- *
- * @code
- *     worksheet_protect(worksheet, "Some Password", options);
- * @endcode
- *
- * The `password` and lxw_protection pointer are both optional:
- *
- * @code
- *     worksheet_protect(worksheet1, NULL,       NULL);
- *     worksheet_protect(worksheet2, NULL,       my_options);
- *     worksheet_protect(worksheet3, "password", NULL);
- *     worksheet_protect(worksheet4, "password", my_options);
- * @endcode
- *
- * Passing a `NULL` password is the same as turning on protection without a
- * password. Passing a `NULL` password and `NULL` options, or any other
- * combination has the effect of enabling a cell's `locked` and `hidden`
- * properties if they have been set.
- *
- * A *locked* cell cannot be edited and this property is on by default for all
- * cells. A *hidden* cell will display the results of a formula but not the
- * formula itself. These properties can be set using the format_set_unlocked()
- * and format_set_hidden() format functions.
- *
- * You can specify which worksheet elements you wish to protect by passing a
- * lxw_protection pointer in the `options` argument with any or all of the
- * following members set:
- *
- *     no_select_locked_cells
- *     no_select_unlocked_cells
- *     format_cells
- *     format_columns
- *     format_rows
- *     insert_columns
- *     insert_rows
- *     insert_hyperlinks
- *     delete_columns
- *     delete_rows
- *     sort
- *     autofilter
- *     pivot_tables
- *     scenarios
- *     objects
- *
- * All parameters are off by default. Individual elements can be protected as
- * follows:
- *
- * @code
- *     lxw_protection options = {
- *         .format_cells             = 1,
- *         .insert_hyperlinks        = 1,
- *         .insert_rows              = 1,
- *         .delete_rows              = 1,
- *         .insert_columns           = 1,
- *         .delete_columns           = 1,
- *     };
- *
- *     worksheet_protect(worksheet, NULL, &options);
- *
- * @endcode
- *
- * See also the format_set_unlocked() and format_set_hidden() format functions.
- *
- * **Note:** Worksheet level passwords in Excel offer **very** weak
- * protection. They don't encrypt your data and are very easy to
- * deactivate. Full workbook encryption is not supported by `libxlsxwriter`
- * since it requires a completely different file format and would take several
- * man months to implement.
- */
-void worksheet_protect(lxw_worksheet *worksheet, const char *password,
-                       lxw_protection *options);
-
-/**
- * @brief Set the Outline and Grouping display properties.
- *
- * @param worksheet      Pointer to a lxw_worksheet instance to be updated.
- * @param visible        Outlines are visible. Optional, defaults to True.
- * @param symbols_below  Show row outline symbols below the outline bar.
- * @param symbols_right  Show column outline symbols to the right of outline.
- * @param auto_style     Use Automatic outline style.
- *
- * The `%worksheet_outline_settings()` method is used to control the
- * appearance of outlines in Excel. Outlines are described the section on
- * @ref working_with_outlines.
- *
- * The `visible` parameter is used to control whether or not outlines are
- * visible. Setting this parameter to False will cause all outlines on the
- * worksheet to be hidden. They can be un-hidden in Excel by means of the
- * "Show Outline Symbols" command button. The default Excel setting is True
- * for visible outlines.
- *
- * The `symbols_below` parameter is used to control whether the row outline
- * symbol will appear above or below the outline level bar. The default Excel
- * setting is True for symbols to appear below the outline level bar.
- *
- * The `symbols_right` parameter is used to control whether the column outline
- * symbol will appear to the left or the right of the outline level bar. The
- * default Excel setting is True for symbols to appear to the right of the
- * outline level bar.
- *
- * The `auto_style` parameter is used to control whether the automatic outline
- * generator in Excel uses automatic styles when creating an outline. This has
- * no effect on a file generated by XlsxWriter but it does have an effect on
- * how the worksheet behaves after it is created. The default Excel setting is
- * False for "Automatic Styles" to be turned off.
- *
- * The default settings for all of these parameters in libxlsxwriter
- * correspond to Excel's default parameters and are shown below:
- *
- * @code
- *     worksheet_outline_settings(worksheet1, LXW_TRUE, LXW_TRUE, LXW_TRUE, LXW_FALSE);
- * @endcode
- *
- * The worksheet parameters controlled by `worksheet_outline_settings()` are
- * rarely used.
- */
-void worksheet_outline_settings(lxw_worksheet *worksheet, uint8_t visible,
-                                uint8_t symbols_below, uint8_t symbols_right,
-                                uint8_t auto_style);
-
-/**
- * @brief Set the default row properties.
- *
- * @param worksheet        Pointer to a lxw_worksheet instance to be updated.
- * @param height           Default row height.
- * @param hide_unused_rows Hide unused cells.
- *
- * The `%worksheet_set_default_row()` function is used to set Excel default
- * row properties such as the default height and the option to hide unused
- * rows. These parameters are an optimization used by Excel to set row
- * properties without generating a very large file with an entry for each row.
- *
- * To set the default row height:
- *
- * @code
- *     worksheet_set_default_row(worksheet, 24, LXW_FALSE);
- *
- * @endcode
- *
- * To hide unused rows:
- *
- * @code
- *     worksheet_set_default_row(worksheet, 15, LXW_TRUE);
- * @endcode
- *
- * Note, in the previous case we use the default height #LXW_DEF_ROW_HEIGHT =
- * 15 so the the height remains unchanged.
- */
-void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
-                               uint8_t hide_unused_rows);
-
-lxw_worksheet *lxw_worksheet_new(lxw_worksheet_init_data *init_data);
-void lxw_worksheet_free(lxw_worksheet *worksheet);
-void lxw_worksheet_assemble_xml_file(lxw_worksheet *worksheet);
-void lxw_worksheet_write_single_row(lxw_worksheet *worksheet);
-
-void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
-                                 uint16_t image_ref_id, uint16_t drawing_id,
-                                 lxw_image_options *image_data);
-
-void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
-                                 uint16_t chart_ref_id, uint16_t drawing_id,
-                                 lxw_image_options *image_data);
-
-lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
-lxw_cell *lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num);
-
-/* Declarations required for unit testing. */
-#ifdef TESTING
-
-STATIC void _worksheet_xml_declaration(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_worksheet(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_dimension(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_sheet_view(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_sheet_views(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_sheet_format_pr(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_sheet_data(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_page_margins(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_page_setup(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_col_info(lxw_worksheet *worksheet,
-                                      lxw_col_options *options);
-STATIC void _write_row(lxw_worksheet *worksheet, lxw_row *row, char *spans);
-STATIC lxw_row *_get_row_list(struct lxw_table_rows *table,
-                              lxw_row_t row_num);
-
-STATIC void _worksheet_write_merge_cell(lxw_worksheet *worksheet,
-                                        lxw_merged_range *merged_range);
-STATIC void _worksheet_write_merge_cells(lxw_worksheet *worksheet);
-
-STATIC void _worksheet_write_odd_header(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_odd_footer(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_header_footer(lxw_worksheet *worksheet);
-
-STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet);
-STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
-#endif /* TESTING */
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __LXW_WORKSHEET_H__ */

+ 0 - 178
library/include/xlsxwriter/xmlwriter.h

@@ -1,178 +0,0 @@
-/*
- * libxlsxwriter
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- * xmlwriter - A libxlsxwriter library for creating Excel XLSX
- *             XML files.
- *
- * The xmlwriter library is used to create the XML sub-components files
- * in the Excel XLSX file format.
- *
- * This library is used in preference to a more generic XML library to allow
- * for customization and optimization for the XLSX file format.
- *
- * The xmlwriter functions are only used internally and do not need to be
- * called directly by the end user.
- *
- */
-#ifndef __XMLWRITER_H__
-#define __XMLWRITER_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include "utility.h"
-
-#define LXW_MAX_ATTRIBUTE_LENGTH 256
-#define LXW_ATTR_32              32
-
-#define LXW_ATTRIBUTE_COPY(dst, src)                    \
-    do{                                                 \
-        strncpy(dst, src, LXW_MAX_ATTRIBUTE_LENGTH -1); \
-        dst[LXW_MAX_ATTRIBUTE_LENGTH - 1] = '\0';       \
-    } while (0)
-
-
- /* *INDENT-OFF* */
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* *INDENT-ON* */
-
-/* Attribute used in XML elements. */
-struct xml_attribute {
-    char key[LXW_MAX_ATTRIBUTE_LENGTH];
-    char value[LXW_MAX_ATTRIBUTE_LENGTH];
-
-    /* Make the struct a queue.h list element. */
-    STAILQ_ENTRY (xml_attribute) list_entries;
-};
-
-/* Use queue.h macros to define the xml_attribute_list type. */
-STAILQ_HEAD(xml_attribute_list, xml_attribute);
-
-/* Create a new attribute struct to add to a xml_attribute_list. */
-struct xml_attribute *lxw_new_attribute_str(const char *key,
-                                            const char *value);
-struct xml_attribute *lxw_new_attribute_int(const char *key, uint32_t value);
-struct xml_attribute *lxw_new_attribute_dbl(const char *key, double value);
-
-/* Macro to initialize the xml_attribute_list pointers. */
-#define LXW_INIT_ATTRIBUTES()                                 \
-    STAILQ_INIT(&attributes)
-
-/* Macro to add attribute string elements to xml_attribute_list. */
-#define LXW_PUSH_ATTRIBUTES_STR(key, value)                   \
-    do {                                                      \
-    attribute = lxw_new_attribute_str((key), (value));        \
-    STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \
-    } while (0)
-
-/* Macro to add attribute int values to xml_attribute_list. */
-#define LXW_PUSH_ATTRIBUTES_INT(key, value)                   \
-    do {                                                      \
-    attribute = lxw_new_attribute_int((key), (value));        \
-    STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \
-    } while (0)
-
-/* Macro to add attribute double values to xml_attribute_list. */
-#define LXW_PUSH_ATTRIBUTES_DBL(key, value)                   \
-    do {                                                      \
-    attribute = lxw_new_attribute_dbl((key), (value));        \
-    STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \
-    } while (0)
-
-/* Macro to free xml_attribute_list and attribute. */
-#define LXW_FREE_ATTRIBUTES()                                 \
-    while (!STAILQ_EMPTY(&attributes)) {                      \
-        attribute = STAILQ_FIRST(&attributes);                \
-        STAILQ_REMOVE_HEAD(&attributes, list_entries);        \
-        free(attribute);                                      \
-    }
-
-/**
- * Create the XML declaration in an XML file.
- *
- * @param xmlfile A FILE pointer to the output XML file.
- */
-void lxw_xml_declaration(FILE * xmlfile);
-
-/**
- * Write an XML start tag with optional attributes.
- *
- * @param xmlfile    A FILE pointer to the output XML file.
- * @param tag        The XML tag to write.
- * @param attributes An optional list of attributes to add to the tag.
- */
-void lxw_xml_start_tag(FILE * xmlfile,
-                       const char *tag,
-                       struct xml_attribute_list *attributes);
-
-/**
- * Write an XML start tag with optional un-encoded attributes.
- * This is a minor optimization for attributes that don't need encoding.
- *
- * @param xmlfile    A FILE pointer to the output XML file.
- * @param tag        The XML tag to write.
- * @param attributes An optional list of attributes to add to the tag.
- */
-void lxw_xml_start_tag_unencoded(FILE * xmlfile,
-                                 const char *tag,
-                                 struct xml_attribute_list *attributes);
-
-/**
- * Write an XML end tag.
- *
- * @param xmlfile    A FILE pointer to the output XML file.
- * @param tag        The XML tag to write.
- */
-void lxw_xml_end_tag(FILE * xmlfile, const char *tag);
-
-/**
- * Write an XML empty tag with optional attributes.
- *
- * @param xmlfile    A FILE pointer to the output XML file.
- * @param tag        The XML tag to write.
- * @param attributes An optional list of attributes to add to the tag.
- */
-void lxw_xml_empty_tag(FILE * xmlfile,
-                       const char *tag,
-                       struct xml_attribute_list *attributes);
-
-/**
- * Write an XML empty tag with optional un-encoded attributes.
- * This is a minor optimization for attributes that don't need encoding.
- *
- * @param xmlfile    A FILE pointer to the output XML file.
- * @param tag        The XML tag to write.
- * @param attributes An optional list of attributes to add to the tag.
- */
-void lxw_xml_empty_tag_unencoded(FILE * xmlfile,
-                                 const char *tag,
-                                 struct xml_attribute_list *attributes);
-
-/**
- * Write an XML element containing data and optional attributes.
- *
- * @param xmlfile    A FILE pointer to the output XML file.
- * @param tag        The XML tag to write.
- * @param data       The data section of the XML element.
- * @param attributes An optional list of attributes to add to the tag.
- */
-void lxw_xml_data_element(FILE * xmlfile,
-                          const char *tag,
-                          const char *data,
-                          struct xml_attribute_list *attributes);
-
-char *lxw_escape_control_characters(const char *string);
-
-char *lxw_escape_data(const char *data);
-
-/* *INDENT-OFF* */
-#ifdef __cplusplus
-}
-#endif
-/* *INDENT-ON* */
-
-#endif /* __XMLWRITER_H__ */

+ 0 - 367
library/include/zip.h

@@ -1,367 +0,0 @@
-/* zip.h -- IO on .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         ---------------------------------------------------------------------------
-
-   Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-        ---------------------------------------------------------------------------
-
-        Changes
-
-        See header of zip.h
-
-*/
-
-/* Pragma added by libxlsxwriter project to avoid warnings with -pedantic -ansi. */
-#ifndef _WIN32
-#pragma GCC system_header
-#endif
-
-#ifndef _zip12_H
-#define _zip12_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* #define HAVE_BZIP2 */
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#ifdef HAVE_BZIP2
-#include "bzlib.h"
-#endif
-
-#define Z_BZIP2ED 12
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK                          (0)
-#define ZIP_EOF                         (0)
-#define ZIP_ERRNO                       (Z_ERRNO)
-#define ZIP_PARAMERROR                  (-102)
-#define ZIP_BADZIPFILE                  (-103)
-#define ZIP_INTERNALERROR               (-104)
-
-#ifndef DEF_MEM_LEVEL
-#  if MAX_MEM_LEVEL >= 8
-#    define DEF_MEM_LEVEL 8
-#  else
-#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#  endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
-    tm_zip      tmz_date;       /* date in understandable format           */
-    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
-/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
-
-    uLong       internal_fa;    /* internal file attributes        2 bytes */
-    uLong       external_fa;    /* external file attributes        4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE        (0)
-#define APPEND_STATUS_CREATEAFTER   (1)
-#define APPEND_STATUS_ADDINZIP      (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
-/*
-  Create a zipfile.
-     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
-       an Unix computer "zlib/zlib113.zip".
-     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
-       will be created at the end of the file.
-         (useful if the file contain a self extractor code)
-     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
-       add files in existing zip (be sure you don't add file that doesn't exist)
-     If the zipfile cannot be opened, the return value is NULL.
-     Else, the return value is a zipFile Handle, usable with other function
-       of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
-   If you want delete file into a zipfile, you must open a zipfile, and create another
-   Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc_def* pzlib_filefunc_def));
-
-extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc64_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level));
-
-extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level,
-                       int zip64));
-
-/*
-  Open a file in the ZIP for writing.
-  filename : the filename in zip (if NULL, '-' without quote will be used
-  *zipfi contain supplemental information
-  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
-    contains the extrafield data the the local header
-  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
-    contains the extrafield data the the local header
-  if comment != NULL, comment contain the comment string
-  method contain the compression method (0 for store, Z_DEFLATED for deflate)
-  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
-                    this MUST be '1' if the uncompressed size is >= 0xffffffff.
-
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw));
-
-
-extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int zip64));
-/*
-  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting));
-
-extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            int zip64
-                                            ));
-
-/*
-  Same than zipOpenNewFileInZip2, except
-    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
-    password : crypting password (NULL for no crypting)
-    crcForCrypting : crc of file to compress (needed for crypting)
- */
-
-extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase
-                                            ));
-
-
-extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase,
-                                            int zip64
-                                            ));
-/*
-  Same than zipOpenNewFileInZip4, except
-    versionMadeBy : value for Version made by field
-    flag : value for flag field (compression level info will be added)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
-                       const void* buf,
-                       unsigned len));
-/*
-  Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
-  Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
-                                            uLong uncompressed_size,
-                                            uLong crc32));
-
-extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
-                                            ZPOS64_T uncompressed_size,
-                                            uLong crc32));
-
-/*
-  Close the current file in the zipfile, for file opened with
-    parameter raw=1 in zipOpenNewFileInZip2
-  uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
-                const char* global_comment));
-/*
-  Close the zipfile
-*/
-
-
-extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
-/*
-  zipRemoveExtraInfoBlock -  Added by Mathias Svensson
-
-  Remove extra information block from a extra information data for the local file header or central directory header
-
-  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
-
-  0x0001 is the signature header for the ZIP64 extra information blocks
-
-  usage.
-                        Remove ZIP64 Extra information from a central director extra field data
-              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
-
-                        Remove ZIP64 Extra information from a Local File Header extra field data
-        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip64_H */

+ 0 - 443
library/src/app.c

@@ -1,443 +0,0 @@
-/*****************************************************************************
- * app - A library for creating Excel XLSX app files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/app.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new app object.
- */
-lxw_app *
-lxw_app_new()
-{
-    lxw_app *app = calloc(1, sizeof(lxw_app));
-    GOTO_LABEL_ON_MEM_ERROR(app, mem_error);
-
-    app->heading_pairs = calloc(1, sizeof(struct lxw_heading_pairs));
-    GOTO_LABEL_ON_MEM_ERROR(app->heading_pairs, mem_error);
-    STAILQ_INIT(app->heading_pairs);
-
-    app->part_names = calloc(1, sizeof(struct lxw_part_names));
-    GOTO_LABEL_ON_MEM_ERROR(app->part_names, mem_error);
-    STAILQ_INIT(app->part_names);
-
-    return app;
-
-mem_error:
-    lxw_app_free(app);
-    return NULL;
-}
-
-/*
- * Free a app object.
- */
-void
-lxw_app_free(lxw_app *app)
-{
-    lxw_heading_pair *heading_pair;
-    lxw_part_name *part_name;
-
-    if (!app)
-        return;
-
-    /* Free the lists in the App object. */
-    if (app->heading_pairs) {
-        while (!STAILQ_EMPTY(app->heading_pairs)) {
-            heading_pair = STAILQ_FIRST(app->heading_pairs);
-            STAILQ_REMOVE_HEAD(app->heading_pairs, list_pointers);
-            free(heading_pair->key);
-            free(heading_pair->value);
-            free(heading_pair);
-        }
-        free(app->heading_pairs);
-    }
-
-    if (app->part_names) {
-        while (!STAILQ_EMPTY(app->part_names)) {
-            part_name = STAILQ_FIRST(app->part_names);
-            STAILQ_REMOVE_HEAD(app->part_names, list_pointers);
-            free(part_name->name);
-            free(part_name);
-        }
-        free(app->part_names);
-    }
-
-    free(app);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_app_xml_declaration(lxw_app *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <Properties> element.
- */
-STATIC void
-_write_properties(lxw_app *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns[] = LXW_SCHEMA_OFFICEDOC "/extended-properties";
-    char xmlns_vt[] = LXW_SCHEMA_OFFICEDOC "/docPropsVTypes";
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:vt", xmlns_vt);
-
-    lxw_xml_start_tag(self->file, "Properties", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <Application> element.
- */
-STATIC void
-_write_application(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "Application", "Microsoft Excel", NULL);
-}
-
-/*
- * Write the <DocSecurity> element.
- */
-STATIC void
-_write_doc_security(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "DocSecurity", "0", NULL);
-}
-
-/*
- * Write the <ScaleCrop> element.
- */
-STATIC void
-_write_scale_crop(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "ScaleCrop", "false", NULL);
-}
-
-/*
- * Write the <vt:lpstr> element.
- */
-STATIC void
-_write_vt_lpstr(lxw_app *self, const char *str)
-{
-    lxw_xml_data_element(self->file, "vt:lpstr", str, NULL);
-}
-
-/*
- * Write the <vt:i4> element.
- */
-STATIC void
-_write_vt_i4(lxw_app *self, const char *value)
-{
-    lxw_xml_data_element(self->file, "vt:i4", value, NULL);
-}
-
-/*
- * Write the <vt:variant> element.
- */
-STATIC void
-_write_vt_variant(lxw_app *self, const char *key, const char *value)
-{
-    /* Write the vt:lpstr element. */
-    lxw_xml_start_tag(self->file, "vt:variant", NULL);
-    _write_vt_lpstr(self, key);
-    lxw_xml_end_tag(self->file, "vt:variant");
-
-    /* Write the vt:i4 element. */
-    lxw_xml_start_tag(self->file, "vt:variant", NULL);
-    _write_vt_i4(self, value);
-    lxw_xml_end_tag(self->file, "vt:variant");
-}
-
-/*
- * Write the <vt:vector> element for the heading pairs.
- */
-STATIC void
-_write_vt_vector_heading_pairs(lxw_app *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_heading_pair *heading_pair;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("size", self->num_heading_pairs * 2);
-    LXW_PUSH_ATTRIBUTES_STR("baseType", "variant");
-
-    lxw_xml_start_tag(self->file, "vt:vector", &attributes);
-
-    STAILQ_FOREACH(heading_pair, self->heading_pairs, list_pointers) {
-        _write_vt_variant(self, heading_pair->key, heading_pair->value);
-    }
-
-    lxw_xml_end_tag(self->file, "vt:vector");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <vt:vector> element for the named parts.
- */
-STATIC void
-_write_vt_vector_lpstr_named_parts(lxw_app *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_part_name *part_name;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("size", self->num_part_names);
-    LXW_PUSH_ATTRIBUTES_STR("baseType", "lpstr");
-
-    lxw_xml_start_tag(self->file, "vt:vector", &attributes);
-
-    STAILQ_FOREACH(part_name, self->part_names, list_pointers) {
-        _write_vt_lpstr(self, part_name->name);
-    }
-
-    lxw_xml_end_tag(self->file, "vt:vector");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <HeadingPairs> element.
- */
-STATIC void
-_write_heading_pairs(lxw_app *self)
-{
-    lxw_xml_start_tag(self->file, "HeadingPairs", NULL);
-
-    /* Write the vt:vector element. */
-    _write_vt_vector_heading_pairs(self);
-
-    lxw_xml_end_tag(self->file, "HeadingPairs");
-}
-
-/*
- * Write the <TitlesOfParts> element.
- */
-STATIC void
-_write_titles_of_parts(lxw_app *self)
-{
-    lxw_xml_start_tag(self->file, "TitlesOfParts", NULL);
-
-    /* Write the vt:vector element. */
-    _write_vt_vector_lpstr_named_parts(self);
-
-    lxw_xml_end_tag(self->file, "TitlesOfParts");
-}
-
-/*
- * Write the <Manager> element.
- */
-STATIC void
-_write_manager(lxw_app *self)
-{
-    lxw_doc_properties *properties = self->properties;
-
-    if (!properties)
-        return;
-
-    if (properties->manager)
-        lxw_xml_data_element(self->file, "Manager", properties->manager,
-                             NULL);
-}
-
-/*
- * Write the <Company> element.
- */
-STATIC void
-_write_company(lxw_app *self)
-{
-    lxw_doc_properties *properties = self->properties;
-
-    if (properties && properties->company)
-        lxw_xml_data_element(self->file, "Company", properties->company,
-                             NULL);
-    else
-        lxw_xml_data_element(self->file, "Company", "", NULL);
-}
-
-/*
- * Write the <LinksUpToDate> element.
- */
-STATIC void
-_write_links_up_to_date(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "LinksUpToDate", "false", NULL);
-}
-
-/*
- * Write the <SharedDoc> element.
- */
-STATIC void
-_write_shared_doc(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "SharedDoc", "false", NULL);
-}
-
-/*
- * Write the <HyperlinkBase> element.
- */
-STATIC void
-_write_hyperlink_base(lxw_app *self)
-{
-    lxw_doc_properties *properties = self->properties;
-
-    if (!properties)
-        return;
-
-    if (properties->hyperlink_base)
-        lxw_xml_data_element(self->file, "HyperlinkBase",
-                             properties->hyperlink_base, NULL);
-}
-
-/*
- * Write the <HyperlinksChanged> element.
- */
-STATIC void
-_write_hyperlinks_changed(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "HyperlinksChanged", "false", NULL);
-}
-
-/*
- * Write the <AppVersion> element.
- */
-STATIC void
-_write_app_version(lxw_app *self)
-{
-    lxw_xml_data_element(self->file, "AppVersion", "12.0000", NULL);
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_app_assemble_xml_file(lxw_app *self)
-{
-
-    /* Write the XML declaration. */
-    _app_xml_declaration(self);
-
-    _write_properties(self);
-    _write_application(self);
-    _write_doc_security(self);
-    _write_scale_crop(self);
-    _write_heading_pairs(self);
-    _write_titles_of_parts(self);
-    _write_manager(self);
-    _write_company(self);
-    _write_links_up_to_date(self);
-    _write_shared_doc(self);
-    _write_hyperlink_base(self);
-    _write_hyperlinks_changed(self);
-    _write_app_version(self);
-
-    lxw_xml_end_tag(self->file, "Properties");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-/*
- * Add the name of a workbook Part such as 'Sheet1' or 'Print_Titles'.
- */
-void
-lxw_app_add_part_name(lxw_app *self, const char *name)
-{
-    lxw_part_name *part_name;
-
-    if (!name)
-        return;
-
-    part_name = calloc(1, sizeof(lxw_part_name));
-    GOTO_LABEL_ON_MEM_ERROR(part_name, mem_error);
-
-    part_name->name = lxw_strdup(name);
-    GOTO_LABEL_ON_MEM_ERROR(part_name->name, mem_error);
-
-    STAILQ_INSERT_TAIL(self->part_names, part_name, list_pointers);
-    self->num_part_names++;
-
-    return;
-
-mem_error:
-    if (part_name) {
-        free(part_name->name);
-        free(part_name);
-    }
-}
-
-/*
- * Add the name of a workbook Heading Pair such as 'Worksheets', 'Charts' or
- * 'Named Ranges'.
- */
-void
-lxw_app_add_heading_pair(lxw_app *self, const char *key, const char *value)
-{
-    lxw_heading_pair *heading_pair;
-
-    if (!key || !value)
-        return;
-
-    heading_pair = calloc(1, sizeof(lxw_heading_pair));
-    GOTO_LABEL_ON_MEM_ERROR(heading_pair, mem_error);
-
-    heading_pair->key = lxw_strdup(key);
-    GOTO_LABEL_ON_MEM_ERROR(heading_pair->key, mem_error);
-
-    heading_pair->value = lxw_strdup(value);
-    GOTO_LABEL_ON_MEM_ERROR(heading_pair->value, mem_error);
-
-    STAILQ_INSERT_TAIL(self->heading_pairs, heading_pair, list_pointers);
-    self->num_heading_pairs++;
-
-    return;
-
-mem_error:
-    if (heading_pair) {
-        free(heading_pair->key);
-        free(heading_pair->value);
-        free(heading_pair);
-    }
-}

+ 0 - 6403
library/src/chart.c

@@ -1,6403 +0,0 @@
-/*****************************************************************************
- * chart - A library for creating Excel XLSX chart files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/chart.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-STATIC void _chart_initialize(lxw_chart *self, uint8_t type);
-STATIC void _chart_axis_set_default_num_format(lxw_chart_axis *axis,
-                                               char *num_format);
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Free a series range object.
- */
-STATIC void
-_chart_free_range(lxw_series_range *range)
-{
-    struct lxw_series_data_point *data_point;
-
-    if (!range)
-        return;
-
-    if (range->data_cache) {
-        while (!STAILQ_EMPTY(range->data_cache)) {
-            data_point = STAILQ_FIRST(range->data_cache);
-            free(data_point->string);
-            STAILQ_REMOVE_HEAD(range->data_cache, list_pointers);
-
-            free(data_point);
-        }
-        free(range->data_cache);
-    }
-
-    free(range->formula);
-    free(range->sheetname);
-    free(range);
-}
-
-STATIC void
-_chart_free_points(lxw_chart_series *series)
-{
-    uint16_t index;
-
-    for (index = 0; index < series->point_count; index++) {
-        lxw_chart_point *point = &series->points[index];
-
-        free(point->line);
-        free(point->fill);
-        free(point->pattern);
-    }
-
-    series->point_count = 0;
-    free(series->points);
-}
-
-/*
- * Free a chart font object.
- */
-STATIC void
-_chart_free_font(lxw_chart_font *font)
-{
-    if (!font)
-        return;
-
-    free(font->name);
-    free(font);
-}
-
-/*
- * Free a series object.
- */
-STATIC void
-_chart_series_free(lxw_chart_series *series)
-{
-    if (!series)
-        return;
-
-    free(series->title.name);
-    free(series->line);
-    free(series->fill);
-    free(series->pattern);
-    free(series->label_num_format);
-    _chart_free_font(series->label_font);
-
-    if (series->marker) {
-        free(series->marker->line);
-        free(series->marker->fill);
-        free(series->marker->pattern);
-        free(series->marker);
-    }
-
-    _chart_free_range(series->categories);
-    _chart_free_range(series->values);
-    _chart_free_range(series->title.range);
-    _chart_free_points(series);
-
-    if (series->x_error_bars) {
-        free(series->x_error_bars->line);
-        free(series->x_error_bars);
-    }
-
-    if (series->y_error_bars) {
-        free(series->y_error_bars->line);
-        free(series->y_error_bars);
-    }
-
-    free(series->trendline_line);
-    free(series->trendline_name);
-
-    free(series);
-}
-
-/*
- * Initialize the data cache in a range object.
- */
-STATIC lxw_error
-_chart_init_data_cache(lxw_series_range *range)
-{
-    /* Initialize the series range data cache. */
-    range->data_cache = calloc(1, sizeof(struct lxw_series_data_points));
-    RETURN_ON_MEM_ERROR(range->data_cache, LXW_ERROR_MEMORY_MALLOC_FAILED);
-    STAILQ_INIT(range->data_cache);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Free a chart object.
- */
-void
-lxw_chart_free(lxw_chart *chart)
-{
-    lxw_chart_series *series;
-
-    if (!chart)
-        return;
-
-    /* Chart series. */
-    if (chart->series_list) {
-        while (!STAILQ_EMPTY(chart->series_list)) {
-            series = STAILQ_FIRST(chart->series_list);
-            STAILQ_REMOVE_HEAD(chart->series_list, list_pointers);
-
-            _chart_series_free(series);
-        }
-
-        free(chart->series_list);
-    }
-
-    /* X Axis. */
-    if (chart->x_axis) {
-        _chart_free_font(chart->x_axis->title.font);
-        _chart_free_font(chart->x_axis->num_font);
-        _chart_free_range(chart->x_axis->title.range);
-        free(chart->x_axis->title.name);
-        free(chart->x_axis->line);
-        free(chart->x_axis->fill);
-        free(chart->x_axis->pattern);
-        free(chart->x_axis->major_gridlines.line);
-        free(chart->x_axis->minor_gridlines.line);
-        free(chart->x_axis->num_format);
-        free(chart->x_axis->default_num_format);
-        free(chart->x_axis);
-    }
-
-    /* Y Axis. */
-    if (chart->y_axis) {
-        _chart_free_font(chart->y_axis->title.font);
-        _chart_free_font(chart->y_axis->num_font);
-        _chart_free_range(chart->y_axis->title.range);
-        free(chart->y_axis->title.name);
-        free(chart->y_axis->line);
-        free(chart->y_axis->fill);
-        free(chart->y_axis->pattern);
-        free(chart->y_axis->major_gridlines.line);
-        free(chart->y_axis->minor_gridlines.line);
-        free(chart->y_axis->num_format);
-        free(chart->y_axis->default_num_format);
-        free(chart->y_axis);
-    }
-
-    /* Chart title. */
-    _chart_free_font(chart->title.font);
-    _chart_free_range(chart->title.range);
-    free(chart->title.name);
-
-    /* Chart legend. */
-    _chart_free_font(chart->legend.font);
-    free(chart->delete_series);
-
-    free(chart->default_marker);
-
-    free(chart->chartarea_line);
-    free(chart->chartarea_fill);
-    free(chart->chartarea_pattern);
-    free(chart->plotarea_line);
-    free(chart->plotarea_fill);
-    free(chart->plotarea_pattern);
-
-    free(chart->drop_lines_line);
-    free(chart->high_low_lines_line);
-
-    free(chart->up_bar_line);
-    free(chart->up_bar_fill);
-    free(chart->down_bar_line);
-    free(chart->down_bar_fill);
-
-    _chart_free_font(chart->table_font);
-
-    free(chart);
-}
-
-/*
- * Create a new chart object.
- */
-lxw_chart *
-lxw_chart_new(uint8_t type)
-{
-    lxw_chart *chart = calloc(1, sizeof(lxw_chart));
-    GOTO_LABEL_ON_MEM_ERROR(chart, mem_error);
-
-    chart->series_list = calloc(1, sizeof(struct lxw_chart_series_list));
-    GOTO_LABEL_ON_MEM_ERROR(chart->series_list, mem_error);
-    STAILQ_INIT(chart->series_list);
-
-    chart->x_axis = calloc(1, sizeof(struct lxw_chart_axis));
-    GOTO_LABEL_ON_MEM_ERROR(chart->x_axis, mem_error);
-
-    chart->y_axis = calloc(1, sizeof(struct lxw_chart_axis));
-    GOTO_LABEL_ON_MEM_ERROR(chart->y_axis, mem_error);
-
-    chart->title.range = calloc(1, sizeof(lxw_series_range));
-    GOTO_LABEL_ON_MEM_ERROR(chart->title.range, mem_error);
-
-    chart->x_axis->title.range = calloc(1, sizeof(lxw_series_range));
-    GOTO_LABEL_ON_MEM_ERROR(chart->x_axis->title.range, mem_error);
-
-    chart->y_axis->title.range = calloc(1, sizeof(lxw_series_range));
-    GOTO_LABEL_ON_MEM_ERROR(chart->y_axis->title.range, mem_error);
-
-    /* Initialize the ranges in the chart titles. */
-    if (_chart_init_data_cache(chart->title.range) != LXW_NO_ERROR)
-        goto mem_error;
-
-    if (_chart_init_data_cache(chart->x_axis->title.range) != LXW_NO_ERROR)
-        goto mem_error;
-
-    if (_chart_init_data_cache(chart->y_axis->title.range) != LXW_NO_ERROR)
-        goto mem_error;
-
-    chart->type = type;
-    chart->style_id = 2;
-    chart->hole_size = 50;
-
-    /* Set the default axis positions. */
-    chart->x_axis->axis_position = LXW_CHART_AXIS_BOTTOM;
-    chart->y_axis->axis_position = LXW_CHART_AXIS_LEFT;
-
-    /* Set the default axis number formats. */
-    _chart_axis_set_default_num_format(chart->x_axis, "General");
-    _chart_axis_set_default_num_format(chart->y_axis, "General");
-
-    chart->x_axis->major_gridlines.visible = LXW_FALSE;
-    chart->y_axis->major_gridlines.visible = LXW_TRUE;
-
-    chart->has_horiz_cat_axis = LXW_FALSE;
-    chart->has_horiz_val_axis = LXW_TRUE;
-
-    chart->legend.position = LXW_CHART_LEGEND_RIGHT;
-
-    chart->gap_y1 = LXW_CHART_DEFAULT_GAP;
-    chart->gap_y2 = LXW_CHART_DEFAULT_GAP;
-
-    /* Initialize the chart specific properties. */
-    _chart_initialize(chart, chart->type);
-
-    return chart;
-
-mem_error:
-    lxw_chart_free(chart);
-    return NULL;
-}
-
-/*
- * Create a copy of a user supplied font.
- */
-STATIC lxw_chart_font *
-_chart_convert_font_args(lxw_chart_font *user_font)
-{
-    lxw_chart_font *font;
-
-    if (!user_font)
-        return NULL;
-
-    font = calloc(1, sizeof(struct lxw_chart_font));
-    RETURN_ON_MEM_ERROR(font, NULL);
-
-    /* Copy the user supplied properties. */
-    font->name = lxw_strdup(user_font->name);
-    font->size = user_font->size;
-    font->bold = user_font->bold;
-    font->italic = user_font->italic;
-    font->underline = user_font->underline;
-    font->rotation = user_font->rotation;
-    font->color = user_font->color;
-    font->pitch_family = user_font->pitch_family;
-    font->charset = user_font->charset;
-    font->baseline = user_font->baseline;
-
-    /* Convert font size units. */
-    if (font->size > 0.0)
-        font->size = font->size * 100.0;
-
-    /* Convert rotation into 60,000ths of a degree. */
-    if (font->rotation)
-        font->rotation = font->rotation * 60000;
-
-    if (font->color) {
-        font->color = lxw_format_check_color(font->color);
-        font->has_color = LXW_TRUE;
-    }
-
-    return font;
-}
-
-/*
- * Create a copy of a user supplied line.
- */
-STATIC lxw_chart_line *
-_chart_convert_line_args(lxw_chart_line *user_line)
-{
-    lxw_chart_line *line;
-
-    if (!user_line)
-        return NULL;
-
-    line = calloc(1, sizeof(struct lxw_chart_line));
-    RETURN_ON_MEM_ERROR(line, NULL);
-
-    /* Copy the user supplied properties. */
-    line->color = user_line->color;
-    line->none = user_line->none;
-    line->width = user_line->width;
-    line->dash_type = user_line->dash_type;
-    line->transparency = user_line->transparency;
-
-    if (line->color) {
-        line->color = lxw_format_check_color(line->color);
-        line->has_color = LXW_TRUE;
-    }
-
-    if (line->transparency > 100)
-        line->transparency = 0;
-
-    return line;
-}
-
-/*
- * Create a copy of a user supplied fill.
- */
-STATIC lxw_chart_fill *
-_chart_convert_fill_args(lxw_chart_fill *user_fill)
-{
-    lxw_chart_fill *fill;
-
-    if (!user_fill)
-        return NULL;
-
-    fill = calloc(1, sizeof(struct lxw_chart_fill));
-    RETURN_ON_MEM_ERROR(fill, NULL);
-
-    /* Copy the user supplied properties. */
-    fill->color = user_fill->color;
-    fill->none = user_fill->none;
-    fill->transparency = user_fill->transparency;
-
-    if (fill->color) {
-        fill->color = lxw_format_check_color(fill->color);
-        fill->has_color = LXW_TRUE;
-    }
-
-    if (fill->transparency > 100)
-        fill->transparency = 0;
-
-    return fill;
-}
-
-/*
- * Create a copy of a user supplied pattern.
- */
-STATIC lxw_chart_pattern *
-_chart_convert_pattern_args(lxw_chart_pattern *user_pattern)
-{
-    lxw_chart_pattern *pattern;
-
-    if (!user_pattern)
-        return NULL;
-
-    if (!user_pattern->type) {
-        LXW_WARN("chart_xxx_set_pattern: 'type' must be specified");
-        return NULL;
-    }
-
-    if (!user_pattern->fg_color) {
-        LXW_WARN("chart_xxx_set_pattern: 'fg_color' must be specified");
-        return NULL;
-    }
-
-    pattern = calloc(1, sizeof(struct lxw_chart_pattern));
-    RETURN_ON_MEM_ERROR(pattern, NULL);
-
-    /* Copy the user supplied properties. */
-    pattern->fg_color = user_pattern->fg_color;
-    pattern->bg_color = user_pattern->bg_color;
-    pattern->type = user_pattern->type;
-
-    pattern->fg_color = lxw_format_check_color(pattern->fg_color);
-    pattern->has_fg_color = LXW_TRUE;
-
-    if (pattern->bg_color) {
-        pattern->bg_color = lxw_format_check_color(pattern->bg_color);
-        pattern->has_bg_color = LXW_TRUE;
-    }
-    else {
-        /* Default background color in Excel is white, when unspecified. */
-        pattern->bg_color = LXW_COLOR_WHITE;
-        pattern->has_bg_color = LXW_TRUE;
-    }
-
-    return pattern;
-}
-
-/*
- * Set a marker type for a series.
- */
-STATIC void
-_chart_set_default_marker_type(lxw_chart *self, uint8_t type)
-{
-    if (!self->default_marker) {
-        lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
-        RETURN_VOID_ON_MEM_ERROR(marker);
-        self->default_marker = marker;
-    }
-
-    self->default_marker->type = type;
-}
-
-/*
- * Set an axis number format.
- */
-void
-_chart_axis_set_default_num_format(lxw_chart_axis *axis, char *num_format)
-{
-    if (!num_format)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->default_num_format);
-
-    axis->default_num_format = lxw_strdup(num_format);
-}
-
-/*
- * Verify that a X/Y error bar property is support for the chart type.
- * All chart types, except Bar have Y error bars. Only Bar and Scatter
- * support X error bars.
- */
-lxw_error
-_chart_check_error_bars(lxw_series_error_bars *error_bars, char *property)
-{
-    /* Check that the error bar type has been set for all error bar
-     * functions except the one that is used to set the type. */
-    if (strlen(property) && !error_bars->is_set) {
-        LXW_WARN_FORMAT1("chart_series_set_error_bars%s(): "
-                         "error bar type must be set first using "
-                         "chart_series_set_error_bars()", property);
-
-        return LXW_ERROR_PARAMETER_VALIDATION;
-    }
-
-    if (error_bars->is_x) {
-        if (error_bars->chart_group != LXW_CHART_SCATTER
-            && error_bars->chart_group != LXW_CHART_BAR) {
-
-            LXW_WARN_FORMAT1("chart_series_set_error_bars%s(): "
-                             "'X error bar' properties only available for"
-                             " Scatter and Bar charts in Excel", property);
-
-            return LXW_ERROR_PARAMETER_VALIDATION;
-        }
-    }
-    else {
-        if (error_bars->chart_group == LXW_CHART_BAR) {
-            LXW_WARN_FORMAT1("chart_series_set_error_bars%s(): "
-                             "'Y error bar' properties not available for "
-                             "Bar charts in Excel", property);
-
-            return LXW_ERROR_PARAMETER_VALIDATION;
-        }
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Add unique ids for primary or secondary axes.
- */
-STATIC void
-_chart_add_axis_ids(lxw_chart *self)
-{
-    uint32_t chart_id = 50010000 + self->id;
-    uint32_t axis_count = 1;
-
-    self->axis_id_1 = chart_id + axis_count;
-    self->axis_id_2 = self->axis_id_1 + 1;
-}
-
-/*
- * Utility function to set a chart range.
- */
-STATIC void
-_chart_set_range(lxw_series_range *range, const char *sheetname,
-                 lxw_row_t first_row, lxw_col_t first_col,
-                 lxw_row_t last_row, lxw_col_t last_col)
-{
-    char formula[LXW_MAX_FORMULA_RANGE_LENGTH] = { 0 };
-
-    /* Set the range properties. */
-    range->sheetname = lxw_strdup(sheetname);
-    range->first_row = first_row;
-    range->first_col = first_col;
-    range->last_row = last_row;
-    range->last_col = last_col;
-
-    /* Free any existing range. */
-    free(range->formula);
-
-    /* Convert the range properties to a formula like: Sheet1!$A$1:$A$5. */
-    lxw_rowcol_to_formula_abs(formula, sheetname,
-                              first_row, first_col, last_row, last_col);
-
-    range->formula = lxw_strdup(formula);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_chart_xml_declaration(lxw_chart *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <c:chartSpace> element.
- */
-STATIC void
-_chart_write_chart_space(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns_c[] = LXW_SCHEMA_DRAWING "/chart";
-    char xmlns_a[] = LXW_SCHEMA_DRAWING "/main";
-    char xmlns_r[] = LXW_SCHEMA_OFFICEDOC "/relationships";
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:c", xmlns_c);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:a", xmlns_a);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
-
-    lxw_xml_start_tag(self->file, "c:chartSpace", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:lang> element.
- */
-STATIC void
-_chart_write_lang(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "en-US");
-
-    lxw_xml_empty_tag(self->file, "c:lang", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:style> element.
- */
-STATIC void
-_chart_write_style(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    /* Don"t write an element for the default style, 2. */
-    if (self->style_id == 2)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", self->style_id);
-
-    lxw_xml_empty_tag(self->file, "c:style", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:layout> element.
- */
-STATIC void
-_chart_write_layout(lxw_chart *self)
-{
-    lxw_xml_empty_tag(self->file, "c:layout", NULL);
-}
-
-/*
- * Write the <c:grouping> element.
- */
-STATIC void
-_chart_write_grouping(lxw_chart *self, uint8_t grouping)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (grouping == LXW_GROUPING_STANDARD)
-        LXW_PUSH_ATTRIBUTES_STR("val", "standard");
-    else if (grouping == LXW_GROUPING_PERCENTSTACKED)
-        LXW_PUSH_ATTRIBUTES_STR("val", "percentStacked");
-    else if (grouping == LXW_GROUPING_STACKED)
-        LXW_PUSH_ATTRIBUTES_STR("val", "stacked");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "clustered");
-
-    lxw_xml_empty_tag(self->file, "c:grouping", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:radarStyle> element.
- */
-STATIC void
-_chart_write_radar_style(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (self->type == LXW_CHART_RADAR_FILLED)
-        LXW_PUSH_ATTRIBUTES_STR("val", "filled");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "marker");
-
-    lxw_xml_empty_tag(self->file, "c:radarStyle", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:varyColors> element.
- */
-STATIC void
-_chart_write_vary_colors(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:varyColors", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:firstSliceAng> element.
- */
-STATIC void
-_chart_write_first_slice_ang(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", self->rotation);
-
-    lxw_xml_empty_tag(self->file, "c:firstSliceAng", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:holeSize> element.
- */
-STATIC void
-_chart_write_hole_size(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", self->hole_size);
-
-    lxw_xml_empty_tag(self->file, "c:holeSize", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:alpha> element.
- */
-STATIC void
-_chart_write_a_alpha(lxw_chart *self, uint8_t transparency)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint32_t val;
-
-    LXW_INIT_ATTRIBUTES();
-
-    val = (100 - transparency) * 1000;
-
-    LXW_PUSH_ATTRIBUTES_INT("val", val);
-
-    lxw_xml_empty_tag(self->file, "a:alpha", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:srgbClr> element.
- */
-STATIC void
-_chart_write_a_srgb_clr(lxw_chart *self, lxw_color_t color,
-                        uint8_t transparency)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char rgb_str[LXW_ATTR_32];
-
-    LXW_INIT_ATTRIBUTES();
-
-    lxw_snprintf(rgb_str, LXW_ATTR_32, "%06X", color & LXW_COLOR_MASK);
-    LXW_PUSH_ATTRIBUTES_STR("val", rgb_str);
-
-    if (transparency) {
-        lxw_xml_start_tag(self->file, "a:srgbClr", &attributes);
-
-        /* Write the a:alpha element. */
-        _chart_write_a_alpha(self, transparency);
-
-        lxw_xml_end_tag(self->file, "a:srgbClr");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "a:srgbClr", &attributes);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:solidFill> element.
- */
-STATIC void
-_chart_write_a_solid_fill(lxw_chart *self, lxw_color_t color,
-                          uint8_t transparency)
-{
-
-    lxw_xml_start_tag(self->file, "a:solidFill", NULL);
-
-    /* Write the a:srgbClr element. */
-    _chart_write_a_srgb_clr(self, color, transparency);
-
-    lxw_xml_end_tag(self->file, "a:solidFill");
-}
-
-/*
- * Write the <a:t> element.
- */
-STATIC void
-_chart_write_a_t(lxw_chart *self, char *name)
-{
-    lxw_xml_data_element(self->file, "a:t", name, NULL);
-}
-
-/*
- * Write the <a:endParaRPr> element.
- */
-STATIC void
-_chart_write_a_end_para_rpr(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("lang", "en-US");
-
-    lxw_xml_empty_tag(self->file, "a:endParaRPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:defRPr> element.
- */
-STATIC void
-_chart_write_a_def_rpr(lxw_chart *self, lxw_chart_font *font)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint8_t has_color = LXW_FALSE;
-    uint8_t has_latin = LXW_FALSE;
-    uint8_t use_font_default = LXW_FALSE;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (font) {
-        has_color = font->color || font->has_color;
-        has_latin = font->name || font->pitch_family || font->charset;
-        use_font_default = !(has_color || has_latin || font->baseline == -1);
-
-        /* Set the font attributes. */
-        if (font->size > 0.0)
-            LXW_PUSH_ATTRIBUTES_DBL("sz", font->size);
-
-        if (use_font_default || font->bold)
-            LXW_PUSH_ATTRIBUTES_INT("b", font->bold & 0x1);
-
-        if (use_font_default || font->italic)
-            LXW_PUSH_ATTRIBUTES_INT("i", font->italic & 0x1);
-
-        if (font->underline)
-            LXW_PUSH_ATTRIBUTES_STR("u", "sng");
-
-        if (font->baseline != -1)
-            LXW_PUSH_ATTRIBUTES_INT("baseline", font->baseline);
-    }
-
-    /* There are sub-elements if the font name or color have changed. */
-    if (has_latin || has_color) {
-
-        lxw_xml_start_tag(self->file, "a:defRPr", &attributes);
-
-        if (has_color) {
-            _chart_write_a_solid_fill(self, font->color, LXW_FALSE);
-        }
-
-        if (has_latin) {
-            /* Free and reuse the attribute list for the latin attributes. */
-            LXW_FREE_ATTRIBUTES();
-
-            if (font->name)
-                LXW_PUSH_ATTRIBUTES_STR("typeface", font->name);
-
-            if (font->pitch_family)
-                LXW_PUSH_ATTRIBUTES_INT("pitchFamily", font->pitch_family);
-
-            if (font->pitch_family || font->charset)
-                LXW_PUSH_ATTRIBUTES_INT("charset", font->charset);
-
-            /* Write the <a:latin> element. */
-            lxw_xml_empty_tag(self->file, "a:latin", &attributes);
-        }
-
-        lxw_xml_end_tag(self->file, "a:defRPr");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "a:defRPr", &attributes);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:rPr> element.
- */
-STATIC void
-_chart_write_a_r_pr(lxw_chart *self, lxw_chart_font *font)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint8_t has_color = LXW_FALSE;
-    uint8_t has_latin = LXW_FALSE;
-    uint8_t use_font_default = LXW_FALSE;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("lang", "en-US");
-
-    if (font) {
-        has_color = font->color || font->has_color;
-        has_latin = font->name || font->pitch_family || font->charset;
-        use_font_default = !(has_color || has_latin || font->baseline == -1);
-
-        /* Set the font attributes. */
-        if (font->size > 0.0)
-            LXW_PUSH_ATTRIBUTES_DBL("sz", font->size);
-
-        if (use_font_default || font->bold)
-            LXW_PUSH_ATTRIBUTES_INT("b", font->bold & 0x1);
-
-        if (use_font_default || font->italic)
-            LXW_PUSH_ATTRIBUTES_INT("i", font->italic & 0x1);
-
-        if (font->underline)
-            LXW_PUSH_ATTRIBUTES_STR("u", "sng");
-
-        if (font->baseline != -1)
-            LXW_PUSH_ATTRIBUTES_INT("baseline", font->baseline);
-    }
-
-    /* There are sub-elements if the font name or color have changed. */
-    if (has_latin || has_color) {
-
-        lxw_xml_start_tag(self->file, "a:rPr", &attributes);
-
-        if (has_color) {
-            _chart_write_a_solid_fill(self, font->color, LXW_FALSE);
-        }
-
-        if (has_latin) {
-            /* Free and reuse the attribute list for the latin attributes. */
-            LXW_FREE_ATTRIBUTES();
-
-            if (font->name)
-                LXW_PUSH_ATTRIBUTES_STR("typeface", font->name);
-
-            if (font->pitch_family)
-                LXW_PUSH_ATTRIBUTES_INT("pitchFamily", font->pitch_family);
-
-            if (font->pitch_family || font->charset)
-                LXW_PUSH_ATTRIBUTES_INT("charset", font->charset);
-
-            /* Write the <a:latin> element. */
-            lxw_xml_empty_tag(self->file, "a:latin", &attributes);
-        }
-
-        lxw_xml_end_tag(self->file, "a:rPr");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "a:rPr", &attributes);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:r> element.
- */
-STATIC void
-_chart_write_a_r(lxw_chart *self, char *name, lxw_chart_font *font)
-{
-    lxw_xml_start_tag(self->file, "a:r", NULL);
-
-    /* Write the a:rPr element. */
-    _chart_write_a_r_pr(self, font);
-
-    /* Write the a:t element. */
-    _chart_write_a_t(self, name);
-
-    lxw_xml_end_tag(self->file, "a:r");
-}
-
-/*
- * Write the <a:pPr> element.
- */
-STATIC void
-_chart_write_a_p_pr_formula(lxw_chart *self, lxw_chart_font *font)
-{
-    lxw_xml_start_tag(self->file, "a:pPr", NULL);
-
-    /* Write the a:defRPr element. */
-    _chart_write_a_def_rpr(self, font);
-
-    lxw_xml_end_tag(self->file, "a:pPr");
-}
-
-/*
- * Write the <a:pPr> element for pie chart legends.
- */
-STATIC void
-_chart_write_a_p_pr_pie(lxw_chart *self, lxw_chart_font *font)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("rtl", "0");
-
-    lxw_xml_start_tag(self->file, "a:pPr", &attributes);
-
-    /* Write the a:defRPr element. */
-    _chart_write_a_def_rpr(self, font);
-
-    lxw_xml_end_tag(self->file, "a:pPr");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:pPr> element.
- */
-STATIC void
-_chart_write_a_p_pr_rich(lxw_chart *self, lxw_chart_font *font)
-{
-    lxw_xml_start_tag(self->file, "a:pPr", NULL);
-
-    /* Write the a:defRPr element. */
-    _chart_write_a_def_rpr(self, font);
-
-    lxw_xml_end_tag(self->file, "a:pPr");
-}
-
-/*
- * Write the <a:p> element.
- */
-STATIC void
-_chart_write_a_p_formula(lxw_chart *self, lxw_chart_font *font)
-{
-    lxw_xml_start_tag(self->file, "a:p", NULL);
-
-    /* Write the a:pPr element. */
-    _chart_write_a_p_pr_formula(self, font);
-
-    /* Write the a:endParaRPr element. */
-    _chart_write_a_end_para_rpr(self);
-
-    lxw_xml_end_tag(self->file, "a:p");
-}
-
-/*
- * Write the <a:p> element for pie chart legends.
- */
-STATIC void
-_chart_write_a_p_pie(lxw_chart *self, lxw_chart_font *font)
-{
-    lxw_xml_start_tag(self->file, "a:p", NULL);
-
-    /* Write the a:pPr element. */
-    _chart_write_a_p_pr_pie(self, font);
-
-    /* Write the a:endParaRPr element. */
-    _chart_write_a_end_para_rpr(self);
-
-    lxw_xml_end_tag(self->file, "a:p");
-}
-
-/*
- * Write the <a:p> element.
- */
-STATIC void
-_chart_write_a_p_rich(lxw_chart *self, char *name, lxw_chart_font *font)
-{
-    lxw_xml_start_tag(self->file, "a:p", NULL);
-
-    /* Write the a:pPr element. */
-    _chart_write_a_p_pr_rich(self, font);
-
-    /* Write the a:r element. */
-    _chart_write_a_r(self, name, font);
-
-    lxw_xml_end_tag(self->file, "a:p");
-}
-
-/*
- * Write the <a:lstStyle> element.
- */
-STATIC void
-_chart_write_a_lst_style(lxw_chart *self)
-{
-    lxw_xml_empty_tag(self->file, "a:lstStyle", NULL);
-}
-
-/*
- * Write the <a:bodyPr> element.
- */
-STATIC void
-_chart_write_a_body_pr(lxw_chart *self, int32_t rotation,
-                       uint8_t is_horizontal)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (rotation == 0 && is_horizontal)
-        rotation = -5400000;
-
-    if (rotation)
-        LXW_PUSH_ATTRIBUTES_INT("rot", rotation);
-
-    if (is_horizontal)
-        LXW_PUSH_ATTRIBUTES_STR("vert", "horz");
-
-    lxw_xml_empty_tag(self->file, "a:bodyPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:ptCount> element.
- */
-STATIC void
-_chart_write_pt_count(lxw_chart *self, uint16_t num_data_points)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", num_data_points);
-
-    lxw_xml_empty_tag(self->file, "c:ptCount", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:v> element.
- */
-STATIC void
-_chart_write_v_num(lxw_chart *self, double number)
-{
-    char data[LXW_ATTR_32];
-
-    lxw_sprintf_dbl(data, number);
-
-    lxw_xml_data_element(self->file, "c:v", data, NULL);
-}
-
-/*
- * Write the <c:v> element.
- */
-STATIC void
-_chart_write_v_str(lxw_chart *self, char *str)
-{
-    lxw_xml_data_element(self->file, "c:v", str, NULL);
-}
-
-/*
- * Write the <c:f> element.
- */
-STATIC void
-_chart_write_f(lxw_chart *self, char *formula)
-{
-    lxw_xml_data_element(self->file, "c:f", formula, NULL);
-}
-
-/*
- * Write the <c:pt> element.
- */
-STATIC void
-_chart_write_pt(lxw_chart *self, uint16_t index,
-                lxw_series_data_point *data_point)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    /* Ignore chart points that have no data. */
-    if (data_point->no_data)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("idx", index);
-
-    lxw_xml_start_tag(self->file, "c:pt", &attributes);
-
-    if (data_point->is_string && data_point->string)
-        _chart_write_v_str(self, data_point->string);
-    else
-        _chart_write_v_num(self, data_point->number);
-
-    lxw_xml_end_tag(self->file, "c:pt");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:pt> element.
- */
-STATIC void
-_chart_write_num_pt(lxw_chart *self, uint16_t index,
-                    lxw_series_data_point *data_point)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    /* Ignore chart points that have no data. */
-    if (data_point->no_data)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("idx", index);
-
-    lxw_xml_start_tag(self->file, "c:pt", &attributes);
-
-    _chart_write_v_num(self, data_point->number);
-
-    lxw_xml_end_tag(self->file, "c:pt");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:formatCode> element.
- */
-STATIC void
-_chart_write_format_code(lxw_chart *self)
-{
-    lxw_xml_data_element(self->file, "c:formatCode", "General", NULL);
-}
-
-/*
- * Write the <c:numCache> element.
- */
-STATIC void
-_chart_write_num_cache(lxw_chart *self, lxw_series_range *range)
-{
-    lxw_series_data_point *data_point;
-    uint16_t index = 0;
-
-    lxw_xml_start_tag(self->file, "c:numCache", NULL);
-
-    /* Write the c:formatCode element. */
-    _chart_write_format_code(self);
-
-    /* Write the c:ptCount element. */
-    _chart_write_pt_count(self, range->num_data_points);
-
-    STAILQ_FOREACH(data_point, range->data_cache, list_pointers) {
-        /* Write the c:pt element. */
-        _chart_write_num_pt(self, index, data_point);
-        index++;
-    }
-
-    lxw_xml_end_tag(self->file, "c:numCache");
-}
-
-/*
- * Write the <c:strCache> element.
- */
-STATIC void
-_chart_write_str_cache(lxw_chart *self, lxw_series_range *range)
-{
-    lxw_series_data_point *data_point;
-    uint16_t index = 0;
-
-    lxw_xml_start_tag(self->file, "c:strCache", NULL);
-
-    /* Write the c:ptCount element. */
-    _chart_write_pt_count(self, range->num_data_points);
-
-    STAILQ_FOREACH(data_point, range->data_cache, list_pointers) {
-        /* Write the c:pt element. */
-        _chart_write_pt(self, index, data_point);
-        index++;
-    }
-
-    lxw_xml_end_tag(self->file, "c:strCache");
-}
-
-/*
- * Write the <c:numRef> element.
- */
-STATIC void
-_chart_write_num_ref(lxw_chart *self, lxw_series_range *range)
-{
-    lxw_xml_start_tag(self->file, "c:numRef", NULL);
-
-    /* Write the c:f element. */
-    _chart_write_f(self, range->formula);
-
-    if (!STAILQ_EMPTY(range->data_cache)) {
-        /* Write the c:numCache element. */
-        _chart_write_num_cache(self, range);
-    }
-
-    lxw_xml_end_tag(self->file, "c:numRef");
-}
-
-/*
- * Write the <c:strRef> element.
- */
-STATIC void
-_chart_write_str_ref(lxw_chart *self, lxw_series_range *range)
-{
-    lxw_xml_start_tag(self->file, "c:strRef", NULL);
-
-    /* Write the c:f element. */
-    _chart_write_f(self, range->formula);
-
-    if (!STAILQ_EMPTY(range->data_cache)) {
-        /* Write the c:strCache element. */
-        _chart_write_str_cache(self, range);
-    }
-
-    lxw_xml_end_tag(self->file, "c:strRef");
-}
-
-/*
- * Write the cached data elements.
- */
-STATIC void
-_chart_write_data_cache(lxw_chart *self, lxw_series_range *range,
-                        uint8_t has_string_cache)
-{
-    if (has_string_cache) {
-        /* Write the c:strRef element. */
-        _chart_write_str_ref(self, range);
-    }
-    else {
-        /* Write the c:numRef element. */
-        _chart_write_num_ref(self, range);
-    }
-}
-
-/*
- * Write the <c:tx> element with a simple value such as for series names.
- */
-STATIC void
-_chart_write_tx_value(lxw_chart *self, char *name)
-{
-    lxw_xml_start_tag(self->file, "c:tx", NULL);
-
-    /* Write the c:v element. */
-    _chart_write_v_str(self, name);
-
-    lxw_xml_end_tag(self->file, "c:tx");
-}
-
-/*
- * Write the <c:tx> element with a simple value such as for series names.
- */
-STATIC void
-_chart_write_tx_formula(lxw_chart *self, lxw_chart_title *title)
-{
-    lxw_xml_start_tag(self->file, "c:tx", NULL);
-
-    _chart_write_str_ref(self, title->range);
-
-    lxw_xml_end_tag(self->file, "c:tx");
-}
-
-/*
- * Write the <c:txPr> element.
- */
-STATIC void
-_chart_write_tx_pr(lxw_chart *self, uint8_t is_horizontal,
-                   lxw_chart_font *font)
-{
-    int32_t rotation = 0;
-
-    if (font)
-        rotation = font->rotation;
-
-    lxw_xml_start_tag(self->file, "c:txPr", NULL);
-
-    /* Write the a:bodyPr element. */
-    _chart_write_a_body_pr(self, rotation, is_horizontal);
-
-    /* Write the a:lstStyle element. */
-    _chart_write_a_lst_style(self);
-
-    /* Write the a:p element. */
-    _chart_write_a_p_formula(self, font);
-
-    lxw_xml_end_tag(self->file, "c:txPr");
-}
-
-/*
- * Write the <c:txPr> element for pie chart legends.
- */
-STATIC void
-_chart_write_tx_pr_pie(lxw_chart *self, uint8_t is_horizontal,
-                       lxw_chart_font *font)
-{
-    int32_t rotation = 0;
-
-    if (font)
-        rotation = font->rotation;
-
-    lxw_xml_start_tag(self->file, "c:txPr", NULL);
-
-    /* Write the a:bodyPr element. */
-    _chart_write_a_body_pr(self, rotation, is_horizontal);
-
-    /* Write the a:lstStyle element. */
-    _chart_write_a_lst_style(self);
-
-    /* Write the a:p element. */
-    _chart_write_a_p_pie(self, font);
-
-    lxw_xml_end_tag(self->file, "c:txPr");
-}
-
-/*
- * Write the <c:txPr> element.
- */
-STATIC void
-_chart_write_axis_font(lxw_chart *self, lxw_chart_font *font)
-{
-    if (!font)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:txPr", NULL);
-
-    /* Write the a:bodyPr element. */
-    _chart_write_a_body_pr(self, font->rotation, LXW_FALSE);
-
-    /* Write the a:lstStyle element. */
-    _chart_write_a_lst_style(self);
-
-    lxw_xml_start_tag(self->file, "a:p", NULL);
-
-    /* Write the a:pPr element. */
-    _chart_write_a_p_pr_rich(self, font);
-
-    /* Write the a:endParaRPr element. */
-    _chart_write_a_end_para_rpr(self);
-
-    lxw_xml_end_tag(self->file, "a:p");
-    lxw_xml_end_tag(self->file, "c:txPr");
-}
-
-/*
- * Write the <c:rich> element.
- */
-STATIC void
-_chart_write_rich(lxw_chart *self, char *name, uint8_t is_horizontal,
-                  lxw_chart_font *font)
-{
-    int32_t rotation = 0;
-
-    if (font)
-        rotation = font->rotation;
-
-    lxw_xml_start_tag(self->file, "c:rich", NULL);
-
-    /* Write the a:bodyPr element. */
-    _chart_write_a_body_pr(self, rotation, is_horizontal);
-
-    /* Write the a:lstStyle element. */
-    _chart_write_a_lst_style(self);
-
-    /* Write the a:p element. */
-    _chart_write_a_p_rich(self, name, font);
-
-    lxw_xml_end_tag(self->file, "c:rich");
-}
-
-/*
- * Write the <c:tx> element.
- */
-STATIC void
-_chart_write_tx_rich(lxw_chart *self, char *name, uint8_t is_horizontal,
-                     lxw_chart_font *font)
-{
-
-    lxw_xml_start_tag(self->file, "c:tx", NULL);
-
-    /* Write the c:rich element. */
-    _chart_write_rich(self, name, is_horizontal, font);
-
-    lxw_xml_end_tag(self->file, "c:tx");
-}
-
-/*
- * Write the <c:title> element for rich strings.
- */
-STATIC void
-_chart_write_title_rich(lxw_chart *self, lxw_chart_title *title)
-{
-    lxw_xml_start_tag(self->file, "c:title", NULL);
-
-    /* Write the c:tx element. */
-    _chart_write_tx_rich(self, title->name, title->is_horizontal,
-                         title->font);
-
-    /* Write the c:layout element. */
-    _chart_write_layout(self);
-
-    lxw_xml_end_tag(self->file, "c:title");
-}
-
-/*
- * Write the <c:title> element for a formula style title
- */
-STATIC void
-_chart_write_title_formula(lxw_chart *self, lxw_chart_title *title)
-{
-    lxw_xml_start_tag(self->file, "c:title", NULL);
-
-    /* Write the c:tx element. */
-    _chart_write_tx_formula(self, title);
-
-    /* Write the c:layout element. */
-    _chart_write_layout(self);
-
-    /* Write the c:txPr element. */
-    _chart_write_tx_pr(self, title->is_horizontal, title->font);
-
-    lxw_xml_end_tag(self->file, "c:title");
-}
-
-/*
- * Write the <c:delete> element.
- */
-STATIC void
-_chart_write_delete(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:delete", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:autoTitleDeleted> element.
- */
-STATIC void
-_chart_write_auto_title_deleted(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:autoTitleDeleted", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:idx> element.
- */
-STATIC void
-_chart_write_idx(lxw_chart *self, uint16_t index)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", index);
-
-    lxw_xml_empty_tag(self->file, "c:idx", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:prstDash> element.
- */
-STATIC void
-_chart_write_a_prst_dash(lxw_chart *self, uint8_t dash_type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (dash_type == LXW_CHART_LINE_DASH_ROUND_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "sysDot");
-    else if (dash_type == LXW_CHART_LINE_DASH_SQUARE_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "sysDash");
-    else if (dash_type == LXW_CHART_LINE_DASH_DASH_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "dashDot");
-    else if (dash_type == LXW_CHART_LINE_DASH_LONG_DASH)
-        LXW_PUSH_ATTRIBUTES_STR("val", "lgDash");
-    else if (dash_type == LXW_CHART_LINE_DASH_LONG_DASH_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "lgDashDot");
-    else if (dash_type == LXW_CHART_LINE_DASH_LONG_DASH_DOT_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "lgDashDotDot");
-    else if (dash_type == LXW_CHART_LINE_DASH_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "dot");
-    else if (dash_type == LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "sysDashDot");
-    else if (dash_type == LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT_DOT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "sysDashDotDot");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "dash");
-
-    lxw_xml_empty_tag(self->file, "a:prstDash", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:noFill> element.
- */
-STATIC void
-_chart_write_a_no_fill(lxw_chart *self)
-{
-    lxw_xml_empty_tag(self->file, "a:noFill", NULL);
-}
-
-/*
- * Write the <a:ln> element.
- */
-STATIC void
-_chart_write_a_ln(lxw_chart *self, lxw_chart_line *line)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    float width_flt;
-    uint32_t width_int;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Round width to nearest 0.25, like Excel. */
-    width_flt = (float) (uint32_t) ((line->width + 0.125) * 4.0F) / 4.0F;
-
-    /* Convert to internal units. */
-    width_int = (uint32_t) (0.5 + (12700.0 * width_flt));
-
-    if (width_int)
-        LXW_PUSH_ATTRIBUTES_INT("w", width_int);
-
-    lxw_xml_start_tag(self->file, "a:ln", &attributes);
-
-    /* Write the line fill. */
-    if (line->none) {
-        /* Write the a:noFill element. */
-        _chart_write_a_no_fill(self);
-    }
-    else if (line->has_color) {
-        /* Write the a:solidFill element. */
-        _chart_write_a_solid_fill(self, line->color, line->transparency);
-    }
-
-    /* Write the line/dash type. */
-    if (line->dash_type) {
-        /* Write the a:prstDash element. */
-        _chart_write_a_prst_dash(self, line->dash_type);
-    }
-
-    lxw_xml_end_tag(self->file, "a:ln");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:fgClr> element.
- */
-STATIC void
-_chart_write_a_fg_clr(lxw_chart *self, lxw_color_t color)
-{
-    lxw_xml_start_tag(self->file, "a:fgClr", NULL);
-
-    _chart_write_a_srgb_clr(self, color, LXW_FALSE);
-
-    lxw_xml_end_tag(self->file, "a:fgClr");
-}
-
-/*
- * Write the <a:bgClr> element.
- */
-STATIC void
-_chart_write_a_bg_clr(lxw_chart *self, lxw_color_t color)
-{
-    lxw_xml_start_tag(self->file, "a:bgClr", NULL);
-
-    _chart_write_a_srgb_clr(self, color, LXW_FALSE);
-
-    lxw_xml_end_tag(self->file, "a:bgClr");
-}
-
-/*
- * Write the <a:pattFill> element.
- */
-STATIC void
-_chart_write_a_patt_fill(lxw_chart *self, lxw_chart_pattern *pattern)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (pattern->type == LXW_CHART_PATTERN_NONE)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "none");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_5)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct5");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_10)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct10");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_20)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct20");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_25)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct25");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_30)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct30");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_40)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct40");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_50)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct50");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_60)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct60");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_70)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct70");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_75)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct75");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_80)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct80");
-    else if (pattern->type == LXW_CHART_PATTERN_PERCENT_90)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "pct90");
-    else if (pattern->type == LXW_CHART_PATTERN_LIGHT_DOWNWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "ltDnDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_LIGHT_UPWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "ltUpDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_DARK_DOWNWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dkDnDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_DARK_UPWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dkUpDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_WIDE_DOWNWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "wdDnDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_WIDE_UPWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "wdUpDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_LIGHT_VERTICAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "ltVert");
-    else if (pattern->type == LXW_CHART_PATTERN_LIGHT_HORIZONTAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "ltHorz");
-    else if (pattern->type == LXW_CHART_PATTERN_NARROW_VERTICAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "narVert");
-    else if (pattern->type == LXW_CHART_PATTERN_NARROW_HORIZONTAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "narHorz");
-    else if (pattern->type == LXW_CHART_PATTERN_DARK_VERTICAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dkVert");
-    else if (pattern->type == LXW_CHART_PATTERN_DARK_HORIZONTAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dkHorz");
-    else if (pattern->type == LXW_CHART_PATTERN_DASHED_DOWNWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dashDnDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_DASHED_UPWARD_DIAGONAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dashUpDiag");
-    else if (pattern->type == LXW_CHART_PATTERN_DASHED_HORIZONTAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dashHorz");
-    else if (pattern->type == LXW_CHART_PATTERN_DASHED_VERTICAL)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dashVert");
-    else if (pattern->type == LXW_CHART_PATTERN_SMALL_CONFETTI)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "smConfetti");
-    else if (pattern->type == LXW_CHART_PATTERN_LARGE_CONFETTI)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "lgConfetti");
-    else if (pattern->type == LXW_CHART_PATTERN_ZIGZAG)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "zigZag");
-    else if (pattern->type == LXW_CHART_PATTERN_WAVE)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "wave");
-    else if (pattern->type == LXW_CHART_PATTERN_DIAGONAL_BRICK)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "diagBrick");
-    else if (pattern->type == LXW_CHART_PATTERN_HORIZONTAL_BRICK)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "horzBrick");
-    else if (pattern->type == LXW_CHART_PATTERN_WEAVE)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "weave");
-    else if (pattern->type == LXW_CHART_PATTERN_PLAID)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "plaid");
-    else if (pattern->type == LXW_CHART_PATTERN_DIVOT)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "divot");
-    else if (pattern->type == LXW_CHART_PATTERN_DOTTED_GRID)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dotGrid");
-    else if (pattern->type == LXW_CHART_PATTERN_DOTTED_DIAMOND)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "dotDmnd");
-    else if (pattern->type == LXW_CHART_PATTERN_SHINGLE)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "shingle");
-    else if (pattern->type == LXW_CHART_PATTERN_TRELLIS)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "trellis");
-    else if (pattern->type == LXW_CHART_PATTERN_SPHERE)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "sphere");
-    else if (pattern->type == LXW_CHART_PATTERN_SMALL_GRID)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "smGrid");
-    else if (pattern->type == LXW_CHART_PATTERN_LARGE_GRID)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "lgGrid");
-    else if (pattern->type == LXW_CHART_PATTERN_SMALL_CHECK)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "smCheck");
-    else if (pattern->type == LXW_CHART_PATTERN_LARGE_CHECK)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "lgCheck");
-    else if (pattern->type == LXW_CHART_PATTERN_OUTLINED_DIAMOND)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "openDmnd");
-    else if (pattern->type == LXW_CHART_PATTERN_SOLID_DIAMOND)
-        LXW_PUSH_ATTRIBUTES_STR("prst", "solidDmnd");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("prst", "percent_50");
-
-    lxw_xml_start_tag(self->file, "a:pattFill", &attributes);
-
-    if (pattern->has_fg_color)
-        _chart_write_a_fg_clr(self, pattern->fg_color);
-
-    if (pattern->has_bg_color)
-        _chart_write_a_bg_clr(self, pattern->bg_color);
-
-    lxw_xml_end_tag(self->file, "a:pattFill");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:spPr> element.
- */
-STATIC void
-_chart_write_sp_pr(lxw_chart *self, lxw_chart_line *line,
-                   lxw_chart_fill *fill, lxw_chart_pattern *pattern)
-{
-    if (!line && !fill && !pattern)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:spPr", NULL);
-
-    /* Write the series fill. Note: a pattern fill overrides a solid fill. */
-    if (fill && !pattern) {
-        if (fill->none) {
-            /* Write the a:noFill element. */
-            _chart_write_a_no_fill(self);
-        }
-        else {
-            /* Write the a:solidFill element. */
-            _chart_write_a_solid_fill(self, fill->color, fill->transparency);
-        }
-    }
-
-    if (pattern) {
-        /* Write the a:pattFill element. */
-        _chart_write_a_patt_fill(self, pattern);
-    }
-
-    if (line) {
-        /* Write the a:ln element. */
-        _chart_write_a_ln(self, line);
-    }
-
-    lxw_xml_end_tag(self->file, "c:spPr");
-}
-
-/*
- * Write the <c:order> element.
- */
-STATIC void
-_chart_write_order(lxw_chart *self, uint16_t index)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", index);
-
-    lxw_xml_empty_tag(self->file, "c:order", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:axId> element.
- */
-STATIC void
-_chart_write_axis_id(lxw_chart *self, uint32_t axis_id)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", axis_id);
-
-    lxw_xml_empty_tag(self->file, "c:axId", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:axId> element.
- */
-STATIC void
-_chart_write_axis_ids(lxw_chart *self)
-{
-    if (!self->axis_id_1)
-        _chart_add_axis_ids(self);
-
-    _chart_write_axis_id(self, self->axis_id_1);
-    _chart_write_axis_id(self, self->axis_id_2);
-}
-
-/*
- * Write the series name.
- */
-STATIC void
-_chart_write_series_name(lxw_chart *self, lxw_chart_series *series)
-{
-    if (series->title.name) {
-        /* Write the c:tx element. */
-        _chart_write_tx_value(self, series->title.name);
-    }
-    else if (series->title.range->formula) {
-        /* Write the c:tx element. */
-        _chart_write_tx_formula(self, &series->title);
-
-    }
-}
-
-/*
- * Write the <c:majorTickMark> element.
- */
-STATIC void
-_chart_write_major_tick_mark(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->major_tick_mark)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (axis->major_tick_mark == LXW_CHART_AXIS_TICK_MARK_NONE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "none");
-    else if (axis->major_tick_mark == LXW_CHART_AXIS_TICK_MARK_INSIDE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "in");
-    else if (axis->major_tick_mark == LXW_CHART_AXIS_TICK_MARK_CROSSING)
-        LXW_PUSH_ATTRIBUTES_STR("val", "cross");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "out");
-
-    lxw_xml_empty_tag(self->file, "c:majorTickMark", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:minorTickMark> element.
- */
-STATIC void
-_chart_write_minor_tick_mark(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->minor_tick_mark)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (axis->minor_tick_mark == LXW_CHART_AXIS_TICK_MARK_NONE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "none");
-    else if (axis->minor_tick_mark == LXW_CHART_AXIS_TICK_MARK_INSIDE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "in");
-    else if (axis->minor_tick_mark == LXW_CHART_AXIS_TICK_MARK_CROSSING)
-        LXW_PUSH_ATTRIBUTES_STR("val", "cross");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "out");
-
-    lxw_xml_empty_tag(self->file, "c:minorTickMark", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:symbol> element.
- */
-STATIC void
-_chart_write_symbol(lxw_chart *self, uint8_t type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (type == LXW_CHART_MARKER_SQUARE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "square");
-    else if (type == LXW_CHART_MARKER_DIAMOND)
-        LXW_PUSH_ATTRIBUTES_STR("val", "diamond");
-    else if (type == LXW_CHART_MARKER_TRIANGLE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "triangle");
-    else if (type == LXW_CHART_MARKER_X)
-        LXW_PUSH_ATTRIBUTES_STR("val", "x");
-    else if (type == LXW_CHART_MARKER_STAR)
-        LXW_PUSH_ATTRIBUTES_STR("val", "star");
-    else if (type == LXW_CHART_MARKER_SHORT_DASH)
-        LXW_PUSH_ATTRIBUTES_STR("val", "short_dash");
-    else if (type == LXW_CHART_MARKER_LONG_DASH)
-        LXW_PUSH_ATTRIBUTES_STR("val", "long_dash");
-    else if (type == LXW_CHART_MARKER_CIRCLE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "circle");
-    else if (type == LXW_CHART_MARKER_PLUS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "plus");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "none");
-
-    lxw_xml_empty_tag(self->file, "c:symbol", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dPt> element.
- */
-STATIC void
-_chart_write_d_pt(lxw_chart *self, lxw_chart_point *point, uint16_t index)
-{
-    lxw_xml_start_tag(self->file, "c:dPt", NULL);
-
-    /* Write the c:idx element. */
-    _chart_write_idx(self, index);
-
-    /* Scatter/Line charts have an additional marker for the point. */
-    if (self->chart_group == LXW_CHART_SCATTER
-        || self->chart_group == LXW_CHART_LINE)
-        lxw_xml_start_tag(self->file, "c:marker", NULL);
-
-    /* Write the c:spPr element. */
-    _chart_write_sp_pr(self, point->line, point->fill, point->pattern);
-
-    if (self->chart_group == LXW_CHART_SCATTER
-        || self->chart_group == LXW_CHART_LINE)
-        lxw_xml_end_tag(self->file, "c:marker");
-
-    lxw_xml_end_tag(self->file, "c:dPt");
-}
-
-/*
- * Write the <c:dPt> element.
- */
-STATIC void
-_chart_write_points(lxw_chart *self, lxw_chart_series *series)
-{
-    uint16_t index;
-
-    for (index = 0; index < series->point_count; index++) {
-        lxw_chart_point *point = &series->points[index];
-
-        /* Ignore empty points. */
-        if (!point->line && !point->fill && !point->pattern)
-            continue;
-
-        /* Write the c:dPt element. */
-        _chart_write_d_pt(self, &series->points[index], index);
-    }
-}
-
-/*
- * Write the <c:invertIfNegative> element.
- */
-STATIC void
-_chart_write_invert_if_negative(lxw_chart *self, lxw_chart_series *series)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!series->invert_if_negative)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:invertIfNegative", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showVal> element.
- */
-STATIC void
-_chart_write_show_val(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showVal", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showCatName> element.
- */
-STATIC void
-_chart_write_show_cat_name(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showCatName", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showSerName> element.
- */
-STATIC void
-_chart_write_show_ser_name(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showSerName", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showLeaderLines> element.
- */
-STATIC void
-_chart_write_show_leader_lines(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showLeaderLines", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dLblPos> element.
- */
-STATIC void
-_chart_write_d_lbl_pos(lxw_chart *self, uint8_t position)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (position == LXW_CHART_LABEL_POSITION_RIGHT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "r");
-    else if (position == LXW_CHART_LABEL_POSITION_LEFT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "l");
-    else if (position == LXW_CHART_LABEL_POSITION_ABOVE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "t");
-    else if (position == LXW_CHART_LABEL_POSITION_BELOW)
-        LXW_PUSH_ATTRIBUTES_STR("val", "b");
-    else if (position == LXW_CHART_LABEL_POSITION_INSIDE_BASE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "inBase");
-    else if (position == LXW_CHART_LABEL_POSITION_INSIDE_END)
-        LXW_PUSH_ATTRIBUTES_STR("val", "inEnd");
-    else if (position == LXW_CHART_LABEL_POSITION_OUTSIDE_END)
-        LXW_PUSH_ATTRIBUTES_STR("val", "outEnd");
-    else if (position == LXW_CHART_LABEL_POSITION_BEST_FIT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "bestFit");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "ctr");
-
-    lxw_xml_empty_tag(self->file, "c:dLblPos", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:separator> element.
- */
-STATIC void
-_chart_write_separator(lxw_chart *self, uint8_t separator)
-{
-    if (separator == LXW_CHART_LABEL_SEPARATOR_SEMICOLON)
-        lxw_xml_data_element(self->file, "c:separator", "; ", NULL);
-    else if (separator == LXW_CHART_LABEL_SEPARATOR_PERIOD)
-        lxw_xml_data_element(self->file, "c:separator", ". ", NULL);
-    else if (separator == LXW_CHART_LABEL_SEPARATOR_NEWLINE)
-        lxw_xml_data_element(self->file, "c:separator", "\n", NULL);
-    else if (separator == LXW_CHART_LABEL_SEPARATOR_SPACE)
-        lxw_xml_data_element(self->file, "c:separator", " ", NULL);
-    else
-        lxw_xml_data_element(self->file, "c:separator", ", ", NULL);
-}
-
-/*
- * Write the <c:showLegendKey> element.
- */
-STATIC void
-_chart_write_show_legend_key(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showLegendKey", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showPercent> element.
- */
-STATIC void
-_chart_write_show_percent(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showPercent", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:numFmt> element.
- */
-STATIC void
-_chart_write_label_num_fmt(lxw_chart *self, char *format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("formatCode", format);
-    LXW_PUSH_ATTRIBUTES_STR("sourceLinked", "0");
-
-    lxw_xml_empty_tag(self->file, "c:numFmt", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dLbls> element.
- */
-STATIC void
-_chart_write_d_lbls(lxw_chart *self, lxw_chart_series *series)
-{
-    if (!series->has_labels)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:dLbls", NULL);
-
-    /* Write the c:numFmt element. */
-    if (series->label_num_format)
-        _chart_write_label_num_fmt(self, series->label_num_format);
-
-    if (series->label_font)
-        _chart_write_tx_pr(self, LXW_FALSE, series->label_font);
-
-    /* Write the c:dLblPos element. */
-    if (series->label_position)
-        _chart_write_d_lbl_pos(self, series->label_position);
-
-    /* Write the c:showLegendKey element. */
-    if (series->show_labels_legend)
-        _chart_write_show_legend_key(self);
-
-    /* Write the c:showVal element. */
-    if (series->show_labels_value)
-        _chart_write_show_val(self);
-
-    /* Write the c:showCatName element. */
-    if (series->show_labels_category)
-        _chart_write_show_cat_name(self);
-
-    /* Write the c:showSerName element. */
-    if (series->show_labels_name)
-        _chart_write_show_ser_name(self);
-
-    /* Write the c:showPercent element. */
-    if (series->show_labels_percent)
-        _chart_write_show_percent(self);
-
-    /* Write the c:separator element. */
-    if (series->label_separator)
-        _chart_write_separator(self, series->label_separator);
-
-    /* Write the c:showLeaderLines element. */
-    if (series->show_labels_leader)
-        _chart_write_show_leader_lines(self);
-
-    lxw_xml_end_tag(self->file, "c:dLbls");
-}
-
-/*
- * Write the <c:intercept> element.
- */
-STATIC void
-_chart_write_intercept(lxw_chart *self, double value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", value);
-
-    lxw_xml_empty_tag(self->file, "c:intercept", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dispRSqr> element.
- */
-STATIC void
-_chart_write_disp_rsqr(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:dispRSqr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:trendlineLbl> element.
- */
-STATIC void
-_chart_write_trendline_lbl(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    lxw_xml_start_tag(self->file, "c:trendlineLbl", NULL);
-
-    lxw_xml_empty_tag(self->file, "c:layout", NULL);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("formatCode", "General");
-    LXW_PUSH_ATTRIBUTES_INT("sourceLinked", 0);
-
-    lxw_xml_empty_tag(self->file, "c:numFmt", &attributes);
-
-    lxw_xml_end_tag(self->file, "c:trendlineLbl");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dispEq> element.
- */
-STATIC void
-_chart_write_disp_eq(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:dispEq", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:period> element.
- */
-STATIC void
-_chart_write_period(lxw_chart *self, uint8_t value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", value);
-
-    lxw_xml_empty_tag(self->file, "c:period", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:forward> element.
- */
-STATIC void
-_chart_write_forward(lxw_chart *self, double value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", value);
-
-    lxw_xml_empty_tag(self->file, "c:forward", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:backward> element.
- */
-STATIC void
-_chart_write_backward(lxw_chart *self, double value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", value);
-
-    lxw_xml_empty_tag(self->file, "c:backward", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:name> element.
- */
-STATIC void
-_chart_write_name(lxw_chart *self, char *name)
-{
-    lxw_xml_data_element(self->file, "c:name", name, NULL);
-}
-
-/*
- * Write the <c:trendlineType> element.
- */
-STATIC void
-_chart_write_trendline_type(lxw_chart *self, uint8_t type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (type == LXW_CHART_TRENDLINE_TYPE_LOG)
-        LXW_PUSH_ATTRIBUTES_STR("val", "log");
-    else if (type == LXW_CHART_TRENDLINE_TYPE_POLY)
-        LXW_PUSH_ATTRIBUTES_STR("val", "poly");
-    else if (type == LXW_CHART_TRENDLINE_TYPE_POWER)
-        LXW_PUSH_ATTRIBUTES_STR("val", "power");
-    else if (type == LXW_CHART_TRENDLINE_TYPE_EXP)
-        LXW_PUSH_ATTRIBUTES_STR("val", "exp");
-    else if (type == LXW_CHART_TRENDLINE_TYPE_AVERAGE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "movingAvg");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "linear");
-
-    lxw_xml_empty_tag(self->file, "c:trendlineType", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:trendline> element.
- */
-STATIC void
-_chart_write_trendline(lxw_chart *self, lxw_chart_series *series)
-{
-    if (!series->has_trendline)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:trendline", NULL);
-
-    /* Write the c:name element. */
-    if (series->trendline_name)
-        _chart_write_name(self, series->trendline_name);
-
-    /* Write the c:spPr element. */
-    _chart_write_sp_pr(self, series->trendline_line, NULL, NULL);
-
-    /* Write the c:trendlineType element. */
-    _chart_write_trendline_type(self, series->trendline_type);
-
-    /* Write the c:order element. */
-    if (series->trendline_type == LXW_CHART_TRENDLINE_TYPE_POLY
-        && series->trendline_value >= 2) {
-
-        _chart_write_order(self, series->trendline_value);
-    }
-
-    /* Write the c:period element. */
-    if (series->trendline_type == LXW_CHART_TRENDLINE_TYPE_AVERAGE
-        && series->trendline_value >= 2) {
-
-        _chart_write_period(self, series->trendline_value);
-    }
-
-    if (series->has_trendline_forecast) {
-        /* Write the c:forward element. */
-        _chart_write_forward(self, series->trendline_forward);
-
-        /* Write the c:backward element. */
-        _chart_write_backward(self, series->trendline_backward);
-    }
-
-    /* Write the c:intercept element. */
-    if (series->has_trendline_intercept)
-        _chart_write_intercept(self, series->trendline_intercept);
-
-    /* Write the c:dispRSqr element. */
-    if (series->has_trendline_r_squared)
-        _chart_write_disp_rsqr(self);
-
-    if (series->has_trendline_equation) {
-        /* Write the c:dispEq element. */
-        _chart_write_disp_eq(self);
-
-        /* Write the c:trendlineLbl element. */
-        _chart_write_trendline_lbl(self);
-
-    }
-
-    lxw_xml_end_tag(self->file, "c:trendline");
-}
-
-/*
- * Write the <c:val> element.
- */
-STATIC void
-_chart_write_error_val(lxw_chart *self, double value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", value);
-
-    lxw_xml_empty_tag(self->file, "c:val", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:noEndCap> element.
- */
-STATIC void
-_chart_write_no_end_cap(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:noEndCap", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:errValType> element.
- */
-STATIC void
-_chart_write_err_val_type(lxw_chart *self, uint8_t type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (type == LXW_CHART_ERROR_BAR_TYPE_FIXED)
-        LXW_PUSH_ATTRIBUTES_STR("val", "fixedVal");
-    else if (type == LXW_CHART_ERROR_BAR_TYPE_PERCENTAGE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "percentage");
-    else if (type == LXW_CHART_ERROR_BAR_TYPE_STD_DEV)
-        LXW_PUSH_ATTRIBUTES_STR("val", "stdDev");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "stdErr");
-
-    lxw_xml_empty_tag(self->file, "c:errValType", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:errBarType> element.
- */
-STATIC void
-_chart_write_err_bar_type(lxw_chart *self, uint8_t direction)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (direction == LXW_CHART_ERROR_BAR_DIR_PLUS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "plus");
-    else if (direction == LXW_CHART_ERROR_BAR_DIR_MINUS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "minus");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "both");
-
-    lxw_xml_empty_tag(self->file, "c:errBarType", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:errDir> element.
- */
-STATIC void
-_chart_write_err_dir(lxw_chart *self, uint8_t is_x)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (is_x)
-        LXW_PUSH_ATTRIBUTES_STR("val", "x");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "y");
-
-    lxw_xml_empty_tag(self->file, "c:errDir", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:errBars> element.
- */
-STATIC void
-_chart_write_err_bars(lxw_chart *self, lxw_series_error_bars *error_bars)
-{
-    if (!error_bars->is_set)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:errBars", NULL);
-
-    /* Write the c:errDir element, except for Column/Bar charts. */
-    if (error_bars->chart_group != LXW_CHART_BAR
-        && error_bars->chart_group != LXW_CHART_COLUMN) {
-
-        _chart_write_err_dir(self, error_bars->is_x);
-    }
-
-    /* Write the c:errBarType element. */
-    _chart_write_err_bar_type(self, error_bars->direction);
-
-    /* Write the c:errValType element. */
-    _chart_write_err_val_type(self, error_bars->type);
-
-    /* Write the c:noEndCap element. */
-    if (error_bars->endcap == LXW_CHART_ERROR_BAR_NO_CAP)
-        _chart_write_no_end_cap(self);
-
-    /* Write the c:val element. */
-    if (error_bars->has_value)
-        _chart_write_error_val(self, error_bars->value);
-
-    /* Write the c:spPr element. */
-    _chart_write_sp_pr(self, error_bars->line, NULL, NULL);
-
-    lxw_xml_end_tag(self->file, "c:errBars");
-}
-
-/*
- * Write the <c:errBars> element.
- */
-STATIC void
-_chart_write_error_bars(lxw_chart *self, lxw_chart_series *series)
-{
-    _chart_write_err_bars(self, series->x_error_bars);
-    _chart_write_err_bars(self, series->y_error_bars);
-}
-
-/*
- * Write the <c:size> element.
- */
-STATIC void
-_chart_write_marker_size(lxw_chart *self, uint8_t size)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", size);
-
-    lxw_xml_empty_tag(self->file, "c:size", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:marker> element.
- */
-STATIC void
-_chart_write_marker(lxw_chart *self, lxw_chart_marker *marker)
-{
-    /* If there isn't a user defined marker use the default, if this chart
-     * type one. The default usually turns the marker off. */
-    if (!marker)
-        marker = self->default_marker;
-
-    if (!marker)
-        return;
-
-    if (marker->type == LXW_CHART_MARKER_AUTOMATIC)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:marker", NULL);
-
-    /* Write the c:symbol element. */
-    _chart_write_symbol(self, marker->type);
-
-    /* Write the c:size element. */
-    if (marker->size)
-        _chart_write_marker_size(self, marker->size);
-
-    /* Write the c:spPr element. */
-    _chart_write_sp_pr(self, marker->line, marker->fill, marker->pattern);
-
-    lxw_xml_end_tag(self->file, "c:marker");
-}
-
-/*
- * Write the <c:marker> element.
- */
-STATIC void
-_chart_write_marker_value(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:marker", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:smooth> element.
- */
-STATIC void
-_chart_write_smooth(lxw_chart *self, uint8_t smooth)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!smooth)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:smooth", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:scatterStyle> element.
- */
-STATIC void
-_chart_write_scatter_style(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (self->type == LXW_CHART_SCATTER_SMOOTH
-        || self->type == LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "smoothMarker");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "lineMarker");
-
-    lxw_xml_empty_tag(self->file, "c:scatterStyle", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:cat> element.
- */
-STATIC void
-_chart_write_cat(lxw_chart *self, lxw_chart_series *series)
-{
-    uint8_t has_string_cache = series->categories->has_string_cache;
-
-    /* Ignore <c:cat> elements for charts without category values. */
-    if (!series->categories->formula)
-        return;
-
-    self->cat_has_num_fmt = !has_string_cache;
-
-    lxw_xml_start_tag(self->file, "c:cat", NULL);
-
-    /* Write the c:numRef element. */
-    _chart_write_data_cache(self, series->categories, has_string_cache);
-
-    lxw_xml_end_tag(self->file, "c:cat");
-}
-
-/*
- * Write the <c:xVal> element.
- */
-STATIC void
-_chart_write_x_val(lxw_chart *self, lxw_chart_series *series)
-{
-    uint8_t has_string_cache = series->categories->has_string_cache;
-
-    lxw_xml_start_tag(self->file, "c:xVal", NULL);
-
-    /* Write the data cache elements. */
-    _chart_write_data_cache(self, series->categories, has_string_cache);
-
-    lxw_xml_end_tag(self->file, "c:xVal");
-}
-
-/*
- * Write the <c:val> element.
- */
-STATIC void
-_chart_write_val(lxw_chart *self, lxw_chart_series *series)
-{
-    lxw_xml_start_tag(self->file, "c:val", NULL);
-
-    /* Write the data cache elements. The string_cache is set to false since
-     * this should always be a number series. */
-    _chart_write_data_cache(self, series->values, LXW_FALSE);
-
-    lxw_xml_end_tag(self->file, "c:val");
-}
-
-/*
- * Write the <c:yVal> element.
- */
-STATIC void
-_chart_write_y_val(lxw_chart *self, lxw_chart_series *series)
-{
-    lxw_xml_start_tag(self->file, "c:yVal", NULL);
-
-    /* Write the data cache elements. The string_cache is set to false since
-     * this should always be a number series. */
-    _chart_write_data_cache(self, series->values, LXW_FALSE);
-
-    lxw_xml_end_tag(self->file, "c:yVal");
-}
-
-/*
- * Write the <c:ser> element.
- */
-STATIC void
-_chart_write_ser(lxw_chart *self, lxw_chart_series *series)
-{
-    uint16_t index = self->series_index++;
-
-    lxw_xml_start_tag(self->file, "c:ser", NULL);
-
-    /* Write the c:idx element. */
-    _chart_write_idx(self, index);
-
-    /* Write the c:order element. */
-    _chart_write_order(self, index);
-
-    /* Write the series name. */
-    _chart_write_series_name(self, series);
-
-    /* Write the c:spPr element. */
-    _chart_write_sp_pr(self, series->line, series->fill, series->pattern);
-
-    /* Write the c:marker element. */
-    _chart_write_marker(self, series->marker);
-
-    /* Write the c:invertIfNegative element. */
-    _chart_write_invert_if_negative(self, series);
-
-    /* Write the char points. */
-    _chart_write_points(self, series);
-
-    /* Write the c:dLbls element. */
-    _chart_write_d_lbls(self, series);
-
-    /* Write the c:trendline element. */
-    _chart_write_trendline(self, series);
-
-    /* Write the c:errBars element. */
-    _chart_write_error_bars(self, series);
-
-    /* Write the c:cat element. */
-    _chart_write_cat(self, series);
-
-    /* Write the c:val element. */
-    _chart_write_val(self, series);
-
-    /* Write the c:smooth element. */
-    if (self->chart_group == LXW_CHART_SCATTER
-        || self->chart_group == LXW_CHART_LINE)
-        _chart_write_smooth(self, series->smooth);
-
-    lxw_xml_end_tag(self->file, "c:ser");
-}
-
-/*
- * Write the <c:ser> element but with c:xVal/c:yVal instead of c:cat/c:val
- * elements.
- */
-STATIC void
-_chart_write_xval_ser(lxw_chart *self, lxw_chart_series *series)
-{
-    uint16_t index = self->series_index++;
-
-    lxw_xml_start_tag(self->file, "c:ser", NULL);
-
-    /* Write the c:idx element. */
-    _chart_write_idx(self, index);
-
-    /* Write the c:order element. */
-    _chart_write_order(self, index);
-
-    /* Write the series name. */
-    _chart_write_series_name(self, series);
-
-    /* Write the c:spPr element. */
-    _chart_write_sp_pr(self, series->line, series->fill, series->pattern);
-
-    /* Write the c:marker element. */
-    _chart_write_marker(self, series->marker);
-
-    /* Write the char points. */
-    _chart_write_points(self, series);
-
-    /* Write the c:dLbls element. */
-    _chart_write_d_lbls(self, series);
-
-    /* Write the c:trendline element. */
-    _chart_write_trendline(self, series);
-
-    /* Write the c:errBars element. */
-    _chart_write_error_bars(self, series);
-
-    /* Write the c:xVal element. */
-    _chart_write_x_val(self, series);
-
-    /* Write the yVal element. */
-    _chart_write_y_val(self, series);
-
-    /* Write the c:smooth element. */
-    _chart_write_smooth(self, series->smooth);
-
-    lxw_xml_end_tag(self->file, "c:ser");
-}
-
-/*
- * Write the <c:orientation> element.
- */
-STATIC void
-_chart_write_orientation(lxw_chart *self, uint8_t reverse)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    if (reverse)
-        LXW_PUSH_ATTRIBUTES_STR("val", "maxMin");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "minMax");
-
-    lxw_xml_empty_tag(self->file, "c:orientation", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:max> element.
- */
-STATIC void
-_chart_write_max(lxw_chart *self, double max)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", max);
-
-    lxw_xml_empty_tag(self->file, "c:max", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:min> element.
- */
-STATIC void
-_chart_write_min(lxw_chart *self, double min)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", min);
-
-    lxw_xml_empty_tag(self->file, "c:min", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:logBase> element.
- */
-STATIC void
-_chart_write_log_base(lxw_chart *self, uint16_t log_base)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!log_base)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", log_base);
-
-    lxw_xml_empty_tag(self->file, "c:logBase", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:scaling> element.
- */
-STATIC void
-_chart_write_scaling(lxw_chart *self, uint8_t reverse,
-                     uint8_t has_min, double min,
-                     uint8_t has_max, double max, uint16_t log_base)
-{
-    lxw_xml_start_tag(self->file, "c:scaling", NULL);
-
-    /* Write the c:logBase element. */
-    _chart_write_log_base(self, log_base);
-
-    /* Write the c:orientation element. */
-    _chart_write_orientation(self, reverse);
-
-    if (has_max) {
-        /* Write the c:max element. */
-        _chart_write_max(self, max);
-    }
-
-    if (has_min) {
-        /* Write the c:min element. */
-        _chart_write_min(self, min);
-    }
-
-    lxw_xml_end_tag(self->file, "c:scaling");
-}
-
-/*
- * Write the <c:axPos> element.
- */
-STATIC void
-_chart_write_axis_pos(lxw_chart *self, uint8_t position, uint8_t reverse)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Reverse the axis direction if required. */
-    position ^= reverse;
-
-    if (position == LXW_CHART_AXIS_RIGHT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "r");
-    else if (position == LXW_CHART_AXIS_LEFT)
-        LXW_PUSH_ATTRIBUTES_STR("val", "l");
-    else if (position == LXW_CHART_AXIS_TOP)
-        LXW_PUSH_ATTRIBUTES_STR("val", "t");
-    else if (position == LXW_CHART_AXIS_BOTTOM)
-        LXW_PUSH_ATTRIBUTES_STR("val", "b");
-
-    lxw_xml_empty_tag(self->file, "c:axPos", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:tickLblPos> element.
- */
-STATIC void
-_chart_write_tick_label_pos(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (axis->label_position == LXW_CHART_AXIS_LABEL_POSITION_HIGH)
-        LXW_PUSH_ATTRIBUTES_STR("val", "high");
-    else if (axis->label_position == LXW_CHART_AXIS_LABEL_POSITION_LOW)
-        LXW_PUSH_ATTRIBUTES_STR("val", "low");
-    else if (axis->label_position == LXW_CHART_AXIS_LABEL_POSITION_NONE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "none");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "nextTo");
-
-    lxw_xml_empty_tag(self->file, "c:tickLblPos", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:crossAx> element.
- */
-STATIC void
-_chart_write_cross_axis(lxw_chart *self, uint32_t axis_id)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", axis_id);
-
-    lxw_xml_empty_tag(self->file, "c:crossAx", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:crosses> element.
- */
-STATIC void
-_chart_write_crosses(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (axis->crossing_max)
-        LXW_PUSH_ATTRIBUTES_STR("val", "max");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "autoZero");
-
-    lxw_xml_empty_tag(self->file, "c:crosses", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:crossesAt> element.
- */
-STATIC void
-_chart_write_crosses_at(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_DBL("val", axis->crossing);
-
-    lxw_xml_empty_tag(self->file, "c:crossesAt", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:auto> element.
- */
-STATIC void
-_chart_write_auto(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:auto", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:lblAlgn> element.
- */
-STATIC void
-_chart_write_label_align(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "ctr");
-
-    lxw_xml_empty_tag(self->file, "c:lblAlgn", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:tickLblSkip> element.
- */
-STATIC void
-_chart_write_tick_label_skip(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->interval_unit)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", axis->interval_unit);
-
-    lxw_xml_empty_tag(self->file, "c:tickLblSkip", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:tickMarkSkip> element.
- */
-STATIC void
-_chart_write_tick_mark_skip(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->interval_tick)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", axis->interval_tick);
-
-    lxw_xml_empty_tag(self->file, "c:tickMarkSkip", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:majorUnit> element.
- */
-STATIC void
-_chart_write_major_unit(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->has_major_unit)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", axis->major_unit);
-
-    lxw_xml_empty_tag(self->file, "c:majorUnit", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:minorUnit> element.
- */
-STATIC void
-_chart_write_minor_unit(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->has_minor_unit)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", axis->minor_unit);
-
-    lxw_xml_empty_tag(self->file, "c:minorUnit", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dispUnits> element.
- */
-STATIC void
-_chart_write_disp_units(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!axis->display_units)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    lxw_xml_start_tag(self->file, "c:dispUnits", NULL);
-
-    if (axis->display_units == LXW_CHART_AXIS_UNITS_HUNDREDS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "hundreds");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_THOUSANDS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "thousands");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_TEN_THOUSANDS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "tenThousands");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_HUNDRED_THOUSANDS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "hundredThousands");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_MILLIONS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "millions");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_TEN_MILLIONS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "tenMillions");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_HUNDRED_MILLIONS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "hundredMillions");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_BILLIONS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "billions");
-    else if (axis->display_units == LXW_CHART_AXIS_UNITS_TRILLIONS)
-        LXW_PUSH_ATTRIBUTES_STR("val", "trillions");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "hundreds");
-
-    lxw_xml_empty_tag(self->file, "c:builtInUnit", &attributes);
-
-    if (axis->display_units_visible) {
-        lxw_xml_start_tag(self->file, "c:dispUnitsLbl", NULL);
-        lxw_xml_empty_tag(self->file, "c:layout", NULL);
-        lxw_xml_end_tag(self->file, "c:dispUnitsLbl");
-    }
-
-    lxw_xml_end_tag(self->file, "c:dispUnits");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:lblOffset> element.
- */
-STATIC void
-_chart_write_label_offset(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "100");
-
-    lxw_xml_empty_tag(self->file, "c:lblOffset", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:majorGridlines> element.
- */
-STATIC void
-_chart_write_major_gridlines(lxw_chart *self, lxw_chart_axis *axis)
-{
-    if (!axis->major_gridlines.visible)
-        return;
-
-    if (axis->major_gridlines.line) {
-        lxw_xml_start_tag(self->file, "c:majorGridlines", NULL);
-
-        /* Write the c:spPr element for the axis line. */
-        _chart_write_sp_pr(self, axis->major_gridlines.line, NULL, NULL);
-
-        lxw_xml_end_tag(self->file, "c:majorGridlines");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "c:majorGridlines", NULL);
-    }
-}
-
-/*
- * Write the <c:minorGridlines> element.
- */
-STATIC void
-_chart_write_minor_gridlines(lxw_chart *self, lxw_chart_axis *axis)
-{
-    if (!axis->minor_gridlines.visible)
-        return;
-
-    if (axis->minor_gridlines.line) {
-        lxw_xml_start_tag(self->file, "c:minorGridlines", NULL);
-
-        /* Write the c:spPr element for the axis line. */
-        _chart_write_sp_pr(self, axis->minor_gridlines.line, NULL, NULL);
-
-        lxw_xml_end_tag(self->file, "c:minorGridlines");
-
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "c:minorGridlines", NULL);
-    }
-}
-
-/*
- * Write the <c:numberFormat> element. Note: It is assumed that if a user
- * defined number format is supplied (i.e., non-default) then the sourceLinked
- * attribute is 0. The user can override this if required.
- */
-STATIC void
-_chart_write_number_format(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char *num_format;
-    uint8_t source_linked = 1;
-
-    /* Set the number format to the axis default if not set. */
-    if (axis->num_format)
-        num_format = axis->num_format;
-    else
-        num_format = axis->default_num_format;
-
-    /* Check if a user defined number format has been set. */
-    if (strcmp(num_format, axis->default_num_format))
-        source_linked = 0;
-
-    /* Allow override of sourceLinked. */
-    if (axis->source_linked)
-        source_linked = 1;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("formatCode", num_format);
-    LXW_PUSH_ATTRIBUTES_INT("sourceLinked", source_linked);
-
-    lxw_xml_empty_tag(self->file, "c:numFmt", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:numFmt> element. Special case handler for category axes which
- * don't always have a number format.
- */
-STATIC void
-_chart_write_cat_number_format(lxw_chart *self, lxw_chart_axis *axis)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char *num_format;
-    uint8_t source_linked = 1;
-    uint8_t default_format = LXW_TRUE;
-
-    /* Set the number format to the axis default if not set. */
-    if (axis->num_format)
-        num_format = axis->num_format;
-    else
-        num_format = axis->default_num_format;
-
-    /* Check if a user defined number format has been set. */
-    if (strcmp(num_format, axis->default_num_format)) {
-        source_linked = 0;
-        default_format = LXW_FALSE;
-    }
-
-    /* Allow override of sourceLinked. */
-    if (axis->source_linked)
-        source_linked = 1;
-
-    /* Skip if cat doesn't have a num format (unless it is non-default). */
-    if (!self->cat_has_num_fmt && default_format)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("formatCode", num_format);
-    LXW_PUSH_ATTRIBUTES_INT("sourceLinked", source_linked);
-
-    lxw_xml_empty_tag(self->file, "c:numFmt", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:crossBetween> element.
- */
-STATIC void
-_chart_write_cross_between(lxw_chart *self, uint8_t position)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!position)
-        position = self->default_cross_between;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (position == LXW_CHART_AXIS_POSITION_ON_TICK)
-        LXW_PUSH_ATTRIBUTES_STR("val", "midCat");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "between");
-
-    lxw_xml_empty_tag(self->file, "c:crossBetween", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:overlay> element.
- */
-STATIC void
-_chart_write_overlay(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:overlay", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:legendPos> element.
- */
-STATIC void
-_chart_write_legend_pos(lxw_chart *self, char *position)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("val", position);
-
-    lxw_xml_empty_tag(self->file, "c:legendPos", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:legendEntry> element.
- */
-STATIC void
-_chart_write_legend_entry(lxw_chart *self, uint16_t index)
-{
-    lxw_xml_start_tag(self->file, "c:legendEntry", NULL);
-
-    /* Write the c:idx element. */
-    _chart_write_idx(self, self->delete_series[index]);
-
-    /* Write the c:delete element. */
-    _chart_write_delete(self);
-
-    lxw_xml_end_tag(self->file, "c:legendEntry");
-}
-
-/*
- * Write the <c:legend> element.
- */
-STATIC void
-_chart_write_legend(lxw_chart *self)
-{
-    uint8_t has_overlay = LXW_FALSE;
-    uint16_t index;
-
-    if (self->legend.position == LXW_CHART_LEGEND_NONE)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:legend", NULL);
-
-    /* Write the c:legendPos element. */
-    switch (self->legend.position) {
-        case LXW_CHART_LEGEND_LEFT:
-            _chart_write_legend_pos(self, "l");
-            break;
-        case LXW_CHART_LEGEND_TOP:
-            _chart_write_legend_pos(self, "t");
-            break;
-        case LXW_CHART_LEGEND_BOTTOM:
-            _chart_write_legend_pos(self, "b");
-            break;
-        case LXW_CHART_LEGEND_OVERLAY_RIGHT:
-            _chart_write_legend_pos(self, "r");
-            has_overlay = LXW_TRUE;
-            break;
-        case LXW_CHART_LEGEND_OVERLAY_LEFT:
-            _chart_write_legend_pos(self, "l");
-            has_overlay = LXW_TRUE;
-            break;
-        default:
-            _chart_write_legend_pos(self, "r");
-    }
-
-    /* Remove series labels from the legend. */
-    for (index = 0; index < self->delete_series_count; index++) {
-        /* Write the c:legendEntry element. */
-        _chart_write_legend_entry(self, index);
-    }
-
-    /* Write the c:layout element. */
-    _chart_write_layout(self);
-
-    if (self->chart_group == LXW_CHART_PIE
-        || self->chart_group == LXW_CHART_DOUGHNUT) {
-        /* Write the c:overlay element. */
-        if (has_overlay)
-            _chart_write_overlay(self);
-
-        /* Write the c:txPr element for Pie/Doughnut charts. */
-        _chart_write_tx_pr_pie(self, LXW_FALSE, self->legend.font);
-    }
-    else {
-        /* Write the c:txPr element for all other charts. */
-        if (self->legend.font)
-            _chart_write_tx_pr(self, LXW_FALSE, self->legend.font);
-
-        /* Write the c:overlay element. */
-        if (has_overlay)
-            _chart_write_overlay(self);
-    }
-
-    lxw_xml_end_tag(self->file, "c:legend");
-}
-
-/*
- * Write the <c:plotVisOnly> element.
- */
-STATIC void
-_chart_write_plot_vis_only(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (self->show_hidden_data)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:plotVisOnly", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:headerFooter> element.
- */
-STATIC void
-_chart_write_header_footer(lxw_chart *self)
-{
-    lxw_xml_empty_tag(self->file, "c:headerFooter", NULL);
-}
-
-/*
- * Write the <c:pageMargins> element.
- */
-STATIC void
-_chart_write_page_margins(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("b", "0.75");
-    LXW_PUSH_ATTRIBUTES_STR("l", "0.7");
-    LXW_PUSH_ATTRIBUTES_STR("r", "0.7");
-    LXW_PUSH_ATTRIBUTES_STR("t", "0.75");
-    LXW_PUSH_ATTRIBUTES_STR("header", "0.3");
-    LXW_PUSH_ATTRIBUTES_STR("footer", "0.3");
-
-    lxw_xml_empty_tag(self->file, "c:pageMargins", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:pageSetup> element.
- */
-STATIC void
-_chart_write_page_setup(lxw_chart *self)
-{
-    lxw_xml_empty_tag(self->file, "c:pageSetup", NULL);
-}
-
-/*
- * Write the <c:printSettings> element.
- */
-STATIC void
-_chart_write_print_settings(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:printSettings", NULL);
-
-    /* Write the c:headerFooter element. */
-    _chart_write_header_footer(self);
-
-    /* Write the c:pageMargins element. */
-    _chart_write_page_margins(self);
-
-    /* Write the c:pageSetup element. */
-    _chart_write_page_setup(self);
-
-    lxw_xml_end_tag(self->file, "c:printSettings");
-}
-
-/*
- * Write the <c:overlap> element.
- */
-STATIC void
-_chart_write_overlap(lxw_chart *self, int8_t overlap)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!overlap)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", overlap);
-
-    lxw_xml_empty_tag(self->file, "c:overlap", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:gapWidth> element.
- */
-STATIC void
-_chart_write_gap_width(lxw_chart *self, uint16_t gap)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (gap == LXW_CHART_DEFAULT_GAP)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", gap);
-
-    lxw_xml_empty_tag(self->file, "c:gapWidth", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dispBlanksAs> element.
- */
-STATIC void
-_chart_write_disp_blanks_as(lxw_chart *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (self->show_blanks_as != LXW_CHART_BLANKS_AS_ZERO
-        && self->show_blanks_as != LXW_CHART_BLANKS_AS_CONNECTED)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (self->show_blanks_as == LXW_CHART_BLANKS_AS_ZERO)
-        LXW_PUSH_ATTRIBUTES_STR("val", "zero");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "span");
-
-    lxw_xml_empty_tag(self->file, "c:dispBlanksAs", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showHorzBorder> element.
- */
-STATIC void
-_chart_write_show_horz_border(lxw_chart *self, uint8_t value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!value)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showHorzBorder", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showVertBorder> element.
- */
-STATIC void
-_chart_write_show_vert_border(lxw_chart *self, uint8_t value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!value)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showVertBorder", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showOutline> element.
- */
-STATIC void
-_chart_write_show_outline(lxw_chart *self, uint8_t value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!value)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showOutline", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:showKeys> element.
- */
-STATIC void
-_chart_write_show_keys(lxw_chart *self, uint8_t value)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!value)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("val", "1");
-
-    lxw_xml_empty_tag(self->file, "c:showKeys", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <c:dTable> element.
- */
-STATIC void
-_chart_write_d_table(lxw_chart *self)
-{
-    if (!self->has_table)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:dTable", NULL);
-
-    /* Write the c:showHorzBorder element. */
-    _chart_write_show_horz_border(self, self->has_table_horizontal);
-
-    /* Write the c:showVertBorder element. */
-    _chart_write_show_vert_border(self, self->has_table_vertical);
-
-    /* Write the c:showOutline element. */
-    _chart_write_show_outline(self, self->has_table_outline);
-
-    /* Write the c:showKeys element. */
-    _chart_write_show_keys(self, self->has_table_legend_keys);
-
-    /* Write the c:txPr element. */
-    if (self->table_font)
-        _chart_write_tx_pr(self, LXW_FALSE, self->table_font);
-
-    lxw_xml_end_tag(self->file, "c:dTable");
-}
-
-/*
- * Write the <c:upBars> element.
- */
-STATIC void
-_chart_write_up_bars(lxw_chart *self, lxw_chart_line *line,
-                     lxw_chart_fill *fill)
-{
-    if (line || fill) {
-        lxw_xml_start_tag(self->file, "c:upBars", NULL);
-
-        /* Write the c:spPr element. */
-        _chart_write_sp_pr(self, line, fill, NULL);
-
-        lxw_xml_end_tag(self->file, "c:upBars");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "c:upBars", NULL);
-    }
-}
-
-/*
- * Write the <c:downBars> element.
- */
-STATIC void
-_chart_write_down_bars(lxw_chart *self, lxw_chart_line *line,
-                       lxw_chart_fill *fill)
-{
-    if (line || fill) {
-        lxw_xml_start_tag(self->file, "c:downBars", NULL);
-
-        /* Write the c:spPr element. */
-        _chart_write_sp_pr(self, line, fill, NULL);
-
-        lxw_xml_end_tag(self->file, "c:downBars");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "c:downBars", NULL);
-    }
-}
-
-/*
- * Write the <c:upDownBars> element.
- */
-STATIC void
-_chart_write_up_down_bars(lxw_chart *self)
-{
-    if (!self->has_up_down_bars)
-        return;
-
-    lxw_xml_start_tag(self->file, "c:upDownBars", NULL);
-
-    /* Write the c:gapWidth element. */
-    _chart_write_gap_width(self, 150);
-
-    /* Write the c:upBars element. */
-    _chart_write_up_bars(self, self->up_bar_line, self->up_bar_fill);
-
-    /* Write the c:downBars element. */
-    _chart_write_down_bars(self, self->down_bar_line, self->down_bar_fill);
-
-    lxw_xml_end_tag(self->file, "c:upDownBars");
-}
-
-/*
- * Write the <c:dropLines> element.
- */
-STATIC void
-_chart_write_drop_lines(lxw_chart *self)
-{
-    if (!self->has_drop_lines)
-        return;
-
-    if (self->drop_lines_line) {
-        lxw_xml_start_tag(self->file, "c:dropLines", NULL);
-
-        _chart_write_sp_pr(self, self->drop_lines_line, NULL, NULL);
-
-        lxw_xml_end_tag(self->file, "c:dropLines");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "c:dropLines", NULL);
-    }
-}
-
-/*
- * Write the <c:hiLowLines> element.
- */
-STATIC void
-_chart_write_hi_low_lines(lxw_chart *self)
-{
-    if (!self->has_high_low_lines)
-        return;
-
-    if (self->high_low_lines_line) {
-        lxw_xml_start_tag(self->file, "c:hiLowLines", NULL);
-
-        _chart_write_sp_pr(self, self->high_low_lines_line, NULL, NULL);
-
-        lxw_xml_end_tag(self->file, "c:hiLowLines");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "c:hiLowLines", NULL);
-    }
-}
-
-/*
- * Write the <c:title> element.
- */
-STATIC void
-_chart_write_title(lxw_chart *self, lxw_chart_title *title)
-{
-    if (title->name) {
-        /* Write the c:title element. */
-        _chart_write_title_rich(self, title);
-    }
-    else if (title->range->formula) {
-        /* Write the c:title element. */
-        _chart_write_title_formula(self, title);
-    }
-}
-
-/*
- * Write the <c:title> element.
- */
-STATIC void
-_chart_write_chart_title(lxw_chart *self)
-{
-    if (self->title.off) {
-        /* Write the c:autoTitleDeleted element. */
-        _chart_write_auto_title_deleted(self);
-    }
-    else {
-        /* Write the c:title element. */
-        _chart_write_title(self, &self->title);
-    }
-}
-
-/*
- * Write the <c:catAx> element. Usually the X axis.
- */
-STATIC void
-_chart_write_cat_axis(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:catAx", NULL);
-
-    _chart_write_axis_id(self, self->axis_id_1);
-
-    /* Write the c:scaling element. Note we can't set max, min, or log base
-     * for a Category axis in Excel.*/
-    _chart_write_scaling(self,
-                         self->x_axis->reverse,
-                         LXW_FALSE, 0.0, LXW_FALSE, 0.0, 0);
-
-    /* Write the c:delete element to hide axis. */
-    if (self->x_axis->hidden)
-        _chart_write_delete(self);
-
-    /* Write the c:axPos element. */
-    _chart_write_axis_pos(self, self->x_axis->axis_position,
-                          self->y_axis->reverse);
-
-    /* Write the c:majorGridlines element. */
-    _chart_write_major_gridlines(self, self->x_axis);
-
-    /* Write the c:minorGridlines element. */
-    _chart_write_minor_gridlines(self, self->x_axis);
-
-    /* Write the axis title elements. */
-    self->x_axis->title.is_horizontal = self->has_horiz_cat_axis;
-    _chart_write_title(self, &self->x_axis->title);
-
-    /* Write the c:numFmt element. */
-    _chart_write_cat_number_format(self, self->x_axis);
-
-    /* Write the c:majorTickMark element. */
-    _chart_write_major_tick_mark(self, self->x_axis);
-
-    /* Write the c:minorTickMark element. */
-    _chart_write_minor_tick_mark(self, self->x_axis);
-
-    /* Write the c:tickLblPos element. */
-    _chart_write_tick_label_pos(self, self->x_axis);
-
-    /* Write the c:spPr element for the axis line. */
-    _chart_write_sp_pr(self, self->x_axis->line, self->x_axis->fill,
-                       self->x_axis->pattern);
-
-    /* Write the axis font elements. */
-    _chart_write_axis_font(self, self->x_axis->num_font);
-
-    /* Write the c:crossAx element. */
-    _chart_write_cross_axis(self, self->axis_id_2);
-
-    /* Write the c:crosses element. */
-    if (!self->y_axis->has_crossing || self->y_axis->crossing_max)
-        _chart_write_crosses(self, self->y_axis);
-    else
-        _chart_write_crosses_at(self, self->y_axis);
-
-    /* Write the c:auto element. */
-    _chart_write_auto(self);
-
-    /* Write the c:lblAlgn element. */
-    _chart_write_label_align(self);
-
-    /* Write the c:lblOffset element. */
-    _chart_write_label_offset(self);
-
-    /* Write the c:tickLblSkip element. */
-    _chart_write_tick_label_skip(self, self->x_axis);
-
-    /* Write the c:tickMarkSkip element. */
-    _chart_write_tick_mark_skip(self, self->x_axis);
-
-    lxw_xml_end_tag(self->file, "c:catAx");
-}
-
-/*
- * Write the <c:valAx> element.
- */
-STATIC void
-_chart_write_val_axis(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:valAx", NULL);
-
-    _chart_write_axis_id(self, self->axis_id_2);
-
-    /* Write the c:scaling element. */
-    _chart_write_scaling(self,
-                         self->y_axis->reverse,
-                         self->y_axis->has_min, self->y_axis->min,
-                         self->y_axis->has_max, self->y_axis->max,
-                         self->y_axis->log_base);
-
-    /* Write the c:delete element to hide axis. */
-    if (self->y_axis->hidden)
-        _chart_write_delete(self);
-
-    /* Write the c:axPos element. */
-    _chart_write_axis_pos(self, self->y_axis->axis_position,
-                          self->x_axis->reverse);
-
-    /* Write the c:majorGridlines element. */
-    _chart_write_major_gridlines(self, self->y_axis);
-
-    /* Write the c:minorGridlines element. */
-    _chart_write_minor_gridlines(self, self->y_axis);
-
-    /* Write the axis title elements. */
-    self->y_axis->title.is_horizontal = self->has_horiz_val_axis;
-    _chart_write_title(self, &self->y_axis->title);
-
-    /* Write the c:numFmt element. */
-    _chart_write_number_format(self, self->y_axis);
-
-    /* Write the c:majorTickMark element. */
-    _chart_write_major_tick_mark(self, self->y_axis);
-
-    /* Write the c:minorTickMark element. */
-    _chart_write_minor_tick_mark(self, self->y_axis);
-
-    /* Write the c:tickLblPos element. */
-    _chart_write_tick_label_pos(self, self->y_axis);
-
-    /* Write the c:spPr element for the axis line. */
-    _chart_write_sp_pr(self, self->y_axis->line, self->y_axis->fill,
-                       self->y_axis->pattern);
-
-    /* Write the axis font elements. */
-    _chart_write_axis_font(self, self->y_axis->num_font);
-
-    /* Write the c:crossAx element. */
-    _chart_write_cross_axis(self, self->axis_id_1);
-
-    /* Write the c:crosses element. */
-    if (!self->x_axis->has_crossing || self->x_axis->crossing_max)
-        _chart_write_crosses(self, self->x_axis);
-    else
-        _chart_write_crosses_at(self, self->x_axis);
-
-    /* Write the c:crossBetween element. */
-    _chart_write_cross_between(self, self->x_axis->position_axis);
-
-    /* Write the c:majorUnit element. */
-    _chart_write_major_unit(self, self->y_axis);
-
-    /* Write the c:minorUnit element. */
-    _chart_write_minor_unit(self, self->y_axis);
-
-    /* Write the c:dispUnits element. */
-    _chart_write_disp_units(self, self->y_axis);
-
-    lxw_xml_end_tag(self->file, "c:valAx");
-}
-
-/*
- * Write the <c:valAx> element. This is for the second valAx in scatter plots.
- */
-STATIC void
-_chart_write_cat_val_axis(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:valAx", NULL);
-
-    _chart_write_axis_id(self, self->axis_id_1);
-
-    /* Write the c:scaling element. */
-    _chart_write_scaling(self,
-                         self->x_axis->reverse,
-                         self->x_axis->has_min, self->x_axis->min,
-                         self->x_axis->has_max, self->x_axis->max,
-                         self->x_axis->log_base);
-
-    /* Write the c:delete element to hide axis. */
-    if (self->x_axis->hidden)
-        _chart_write_delete(self);
-
-    /* Write the c:axPos element. */
-    _chart_write_axis_pos(self, self->x_axis->axis_position,
-                          self->y_axis->reverse);
-
-    /* Write the c:majorGridlines element. */
-    _chart_write_major_gridlines(self, self->x_axis);
-
-    /* Write the c:minorGridlines element. */
-    _chart_write_minor_gridlines(self, self->x_axis);
-
-    /* Write the axis title elements. */
-    self->x_axis->title.is_horizontal = self->has_horiz_val_axis;
-    _chart_write_title(self, &self->x_axis->title);
-
-    /* Write the c:numFmt element. */
-    _chart_write_number_format(self, self->x_axis);
-
-    /* Write the c:majorTickMark element. */
-    _chart_write_major_tick_mark(self, self->x_axis);
-
-    /* Write the c:minorTickMark element. */
-    _chart_write_minor_tick_mark(self, self->x_axis);
-
-    /* Write the c:tickLblPos element. */
-    _chart_write_tick_label_pos(self, self->x_axis);
-
-    /* Write the c:spPr element for the axis line. */
-    _chart_write_sp_pr(self, self->x_axis->line, self->x_axis->fill,
-                       self->x_axis->pattern);
-
-    /* Write the axis font elements. */
-    _chart_write_axis_font(self, self->x_axis->num_font);
-
-    /* Write the c:crossAx element. */
-    _chart_write_cross_axis(self, self->axis_id_2);
-
-    /* Write the c:crosses element. */
-    if (!self->y_axis->has_crossing || self->y_axis->crossing_max)
-        _chart_write_crosses(self, self->y_axis);
-    else
-        _chart_write_crosses_at(self, self->y_axis);
-
-    /* Write the c:crossBetween element. */
-    _chart_write_cross_between(self, self->y_axis->position_axis);
-
-    /* Write the c:majorUnit element. */
-    _chart_write_major_unit(self, self->x_axis);
-
-    /* Write the c:minorUnit element. */
-    _chart_write_minor_unit(self, self->x_axis);
-
-    /* Write the c:dispUnits element. */
-    _chart_write_disp_units(self, self->x_axis);
-
-    lxw_xml_end_tag(self->file, "c:valAx");
-}
-
-/*
- * Write the <c:barDir> element.
- */
-STATIC void
-_chart_write_bar_dir(lxw_chart *self, char *type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", type);
-
-    lxw_xml_empty_tag(self->file, "c:barDir", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write a area chart.
- */
-STATIC void
-_chart_write_area_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:areaChart", NULL);
-
-    /* Write the c:grouping element. */
-    _chart_write_grouping(self, self->grouping);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:dropLines element. */
-    _chart_write_drop_lines(self);
-
-    /* Write the c:axId elements. */
-    _chart_write_axis_ids(self);
-
-    lxw_xml_end_tag(self->file, "c:areaChart");
-}
-
-/*
- * Write a bar chart.
- */
-STATIC void
-_chart_write_bar_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:barChart", NULL);
-
-    /* Write the c:barDir element. */
-    _chart_write_bar_dir(self, "bar");
-
-    /* Write the c:grouping element. */
-    _chart_write_grouping(self, self->grouping);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:gapWidth element. */
-    _chart_write_gap_width(self, self->gap_y1);
-
-    /* Write the c:overlap element. */
-    _chart_write_overlap(self, self->overlap_y1);
-
-    /* Write the c:axId elements. */
-    _chart_write_axis_ids(self);
-
-    lxw_xml_end_tag(self->file, "c:barChart");
-}
-
-/*
- * Write a column chart.
- */
-STATIC void
-_chart_write_column_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:barChart", NULL);
-
-    /* Write the c:barDir element. */
-    _chart_write_bar_dir(self, "col");
-
-    /* Write the c:grouping element. */
-    _chart_write_grouping(self, self->grouping);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:gapWidth element. */
-    _chart_write_gap_width(self, self->gap_y1);
-
-    /* Write the c:overlap element. */
-    _chart_write_overlap(self, self->overlap_y1);
-
-    /* Write the c:axId elements. */
-    _chart_write_axis_ids(self);
-
-    lxw_xml_end_tag(self->file, "c:barChart");
-}
-
-/*
- * Write a doughnut chart.
- */
-STATIC void
-_chart_write_doughnut_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:doughnutChart", NULL);
-
-    /* Write the c:varyColors element. */
-    _chart_write_vary_colors(self);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:firstSliceAng element. */
-    _chart_write_first_slice_ang(self);
-
-    /* Write the c:holeSize element. */
-    _chart_write_hole_size(self);
-
-    lxw_xml_end_tag(self->file, "c:doughnutChart");
-}
-
-/*
- * Write a line chart.
- */
-STATIC void
-_chart_write_line_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:lineChart", NULL);
-
-    /* Write the c:grouping element. */
-    _chart_write_grouping(self, self->grouping);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:dropLines element. */
-    _chart_write_drop_lines(self);
-
-    /* Write the c:hiLowLines element. */
-    _chart_write_hi_low_lines(self);
-
-    /* Write the c:upDownBars element. */
-    _chart_write_up_down_bars(self);
-
-    /* Write the c:marker element. */
-    _chart_write_marker_value(self);
-
-    /* Write the c:axId elements. */
-    _chart_write_axis_ids(self);
-
-    lxw_xml_end_tag(self->file, "c:lineChart");
-}
-
-/*
- * Write a pie chart.
- */
-STATIC void
-_chart_write_pie_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:pieChart", NULL);
-
-    /* Write the c:varyColors element. */
-    _chart_write_vary_colors(self);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:firstSliceAng element. */
-    _chart_write_first_slice_ang(self);
-
-    lxw_xml_end_tag(self->file, "c:pieChart");
-}
-
-/*
- * Write a scatter chart.
- */
-STATIC void
-_chart_write_scatter_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:scatterChart", NULL);
-
-    /* Write the c:scatterStyle element. */
-    _chart_write_scatter_style(self);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-
-        /* Add default scatter chart formatting to the series data unless
-         * it has already been specified by the user.*/
-        if (self->type == LXW_CHART_SCATTER) {
-            if (!series->line) {
-                lxw_chart_line line = {
-                    0x000000,
-                    LXW_TRUE,
-                    2.25,
-                    LXW_CHART_LINE_DASH_SOLID,
-                    0,
-                    LXW_FALSE
-                };
-                series->line = _chart_convert_line_args(&line);
-            }
-        }
-
-        /* Write the c:ser element. */
-        _chart_write_xval_ser(self, series);
-    }
-
-    /* Write the c:axId elements. */
-    _chart_write_axis_ids(self);
-
-    lxw_xml_end_tag(self->file, "c:scatterChart");
-}
-
-/*
- * Write a radar chart.
- */
-STATIC void
-_chart_write_radar_chart(lxw_chart *self)
-{
-    lxw_chart_series *series;
-
-    lxw_xml_start_tag(self->file, "c:radarChart", NULL);
-
-    /* Write the c:radarStyle element. */
-    _chart_write_radar_style(self);
-
-    STAILQ_FOREACH(series, self->series_list, list_pointers) {
-        /* Write the c:ser element. */
-        _chart_write_ser(self, series);
-    }
-
-    /* Write the c:axId elements. */
-    _chart_write_axis_ids(self);
-
-    lxw_xml_end_tag(self->file, "c:radarChart");
-}
-
-/*
- * Reverse the opposite axis position if crossing position is "max".
- */
-STATIC void
-_chart_adjust_max_crossing(lxw_chart *self)
-{
-    if (self->x_axis->crossing_max)
-        self->y_axis->axis_position ^= 1;
-
-    if (self->y_axis->crossing_max)
-        self->x_axis->axis_position ^= 1;
-}
-
-/*
- * Write the <c:plotArea> element.
- */
-STATIC void
-_chart_write_scatter_plot_area(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:plotArea", NULL);
-
-    /* Write the c:layout element. */
-    _chart_write_layout(self);
-
-    /* Write subclass chart type elements for primary and secondary axes. */
-    self->write_chart_type(self);
-
-    /* Reverse the opposite axis position if crossing position is "max". */
-    _chart_adjust_max_crossing(self);
-
-    /* Write the c:catAx element. */
-    _chart_write_cat_val_axis(self);
-
-    self->has_horiz_val_axis = LXW_TRUE;
-
-    /* Write the c:valAx element. */
-    _chart_write_val_axis(self);
-
-    /* Write the c:spPr element for the plotarea formatting. */
-    _chart_write_sp_pr(self, self->plotarea_line, self->plotarea_fill,
-                       self->plotarea_pattern);
-
-    lxw_xml_end_tag(self->file, "c:plotArea");
-}
-
-/*
- * Write the <c:plotArea> element. Special handling for pie/doughnut.
- */
-STATIC void
-_chart_write_pie_plot_area(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:plotArea", NULL);
-
-    /* Write the c:layout element. */
-    _chart_write_layout(self);
-
-    /* Write subclass chart type elements for primary and secondary axes. */
-    self->write_chart_type(self);
-
-    /* Write the c:spPr element for the plotarea formatting. */
-    _chart_write_sp_pr(self, self->plotarea_line, self->plotarea_fill,
-                       self->plotarea_pattern);
-
-    lxw_xml_end_tag(self->file, "c:plotArea");
-}
-
-/*
- * Write the <c:plotArea> element.
- */
-STATIC void
-_chart_write_plot_area(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:plotArea", NULL);
-
-    /* Write the c:layout element. */
-    _chart_write_layout(self);
-
-    /* Write subclass chart type elements for primary and secondary axes. */
-    self->write_chart_type(self);
-
-    /* Reverse the opposite axis position if crossing position is "max". */
-    _chart_adjust_max_crossing(self);
-
-    /* Write the c:catAx element. */
-    _chart_write_cat_axis(self);
-
-    /* Write the c:valAx element. */
-    _chart_write_val_axis(self);
-
-    /* Write the c:dTable element. */
-    _chart_write_d_table(self);
-
-    /* Write the c:spPr element for the plotarea formatting. */
-    _chart_write_sp_pr(self, self->plotarea_line, self->plotarea_fill,
-                       self->plotarea_pattern);
-
-    lxw_xml_end_tag(self->file, "c:plotArea");
-}
-
-/*
- * Write the <c:chart> element.
- */
-STATIC void
-_chart_write_chart(lxw_chart *self)
-{
-    lxw_xml_start_tag(self->file, "c:chart", NULL);
-
-    /* Write the c:title element. */
-    _chart_write_chart_title(self);
-
-    /* Write the c:plotArea element. */
-    self->write_plot_area(self);
-
-    /* Write the c:legend element. */
-    _chart_write_legend(self);
-
-    /* Write the c:plotVisOnly element. */
-    _chart_write_plot_vis_only(self);
-
-    /* Write the c:dispBlanksAs element. */
-    _chart_write_disp_blanks_as(self);
-
-    lxw_xml_end_tag(self->file, "c:chart");
-}
-
-/*
- * Initialize a area chart.
- */
-STATIC void
-_chart_initialize_area_chart(lxw_chart *self, uint8_t type)
-{
-    self->chart_group = LXW_CHART_AREA;
-    self->grouping = LXW_GROUPING_STANDARD;
-    self->default_cross_between = LXW_CHART_AXIS_POSITION_ON_TICK;
-    self->x_axis->is_category = LXW_TRUE;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_CENTER;
-
-    if (type == LXW_CHART_AREA_STACKED) {
-        self->grouping = LXW_GROUPING_STACKED;
-        self->subtype = LXW_CHART_SUBTYPE_STACKED;
-    }
-
-    if (type == LXW_CHART_AREA_STACKED_PERCENT) {
-        self->grouping = LXW_GROUPING_PERCENTSTACKED;
-        _chart_axis_set_default_num_format(self->y_axis, "0%");
-        self->subtype = LXW_CHART_SUBTYPE_STACKED;
-    }
-
-    /* Initialize the function pointers for this chart type. */
-    self->write_chart_type = _chart_write_area_chart;
-    self->write_plot_area = _chart_write_plot_area;
-}
-
-/*
- * Swap/reverse the bar chart axes prior to writing. It is the only chart
- * with the category axis in the vertical direction.
- */
-STATIC void
-_chart_swap_bar_axes(lxw_chart *self)
-{
-    lxw_chart_axis *tmp = self->x_axis;
-    self->x_axis = self->y_axis;
-    self->y_axis = tmp;
-}
-
-/*
- * Initialize a bar chart.
- */
-STATIC void
-_chart_initialize_bar_chart(lxw_chart *self, uint8_t type)
-{
-    /* Note: Bar chart category/value axis are reversed in comparison to
-     *       other charts. Some of the defaults reflect this. */
-    self->chart_group = LXW_CHART_BAR;
-    self->x_axis->major_gridlines.visible = LXW_TRUE;
-    self->y_axis->major_gridlines.visible = LXW_FALSE;
-    self->y_axis->is_category = LXW_TRUE;
-    self->x_axis->is_value = LXW_TRUE;
-    self->has_horiz_cat_axis = LXW_TRUE;
-    self->has_horiz_val_axis = LXW_FALSE;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_OUTSIDE_END;
-
-    if (type == LXW_CHART_BAR_STACKED) {
-        self->grouping = LXW_GROUPING_STACKED;
-        self->has_overlap = LXW_TRUE;
-        self->subtype = LXW_CHART_SUBTYPE_STACKED;
-        self->overlap_y1 = 100;
-
-    }
-
-    if (type == LXW_CHART_BAR_STACKED_PERCENT) {
-        self->grouping = LXW_GROUPING_PERCENTSTACKED;
-        _chart_axis_set_default_num_format(self->x_axis, "0%");
-        self->has_overlap = LXW_TRUE;
-        self->subtype = LXW_CHART_SUBTYPE_STACKED;
-        self->overlap_y1 = 100;
-    }
-
-    /* Initialize the function pointers for this chart type. */
-    self->write_chart_type = _chart_write_bar_chart;
-    self->write_plot_area = _chart_write_plot_area;
-}
-
-/*
- * Initialize a column chart.
- */
-STATIC void
-_chart_initialize_column_chart(lxw_chart *self, uint8_t type)
-{
-    self->chart_group = LXW_CHART_COLUMN;
-    self->has_horiz_val_axis = LXW_FALSE;
-    self->x_axis->is_category = LXW_TRUE;
-    self->y_axis->is_value = LXW_TRUE;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_OUTSIDE_END;
-
-    if (type == LXW_CHART_COLUMN_STACKED) {
-        self->grouping = LXW_GROUPING_STACKED;
-        self->has_overlap = LXW_TRUE;
-        self->subtype = LXW_CHART_SUBTYPE_STACKED;
-        self->overlap_y1 = 100;
-    }
-
-    if (type == LXW_CHART_COLUMN_STACKED_PERCENT) {
-        self->grouping = LXW_GROUPING_PERCENTSTACKED;
-        _chart_axis_set_default_num_format(self->y_axis, "0%");
-        self->has_overlap = LXW_TRUE;
-        self->subtype = LXW_CHART_SUBTYPE_STACKED;
-        self->overlap_y1 = 100;
-    }
-
-    /* Initialize the function pointers for this chart type. */
-    self->write_chart_type = _chart_write_column_chart;
-    self->write_plot_area = _chart_write_plot_area;
-}
-
-/*
- * Initialize a doughnut chart.
- */
-STATIC void
-_chart_initialize_doughnut_chart(lxw_chart *self)
-{
-    /* Initialize the function pointers for this chart type. */
-    self->chart_group = LXW_CHART_DOUGHNUT;
-    self->write_chart_type = _chart_write_doughnut_chart;
-    self->write_plot_area = _chart_write_pie_plot_area;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_BEST_FIT;
-}
-
-/*
- * Initialize a line chart.
- */
-STATIC void
-_chart_initialize_line_chart(lxw_chart *self)
-{
-    self->chart_group = LXW_CHART_LINE;
-    _chart_set_default_marker_type(self, LXW_CHART_MARKER_NONE);
-    self->grouping = LXW_GROUPING_STANDARD;
-    self->x_axis->is_category = LXW_TRUE;
-    self->y_axis->is_value = LXW_TRUE;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_RIGHT;
-
-    /* Initialize the function pointers for this chart type. */
-    self->write_chart_type = _chart_write_line_chart;
-    self->write_plot_area = _chart_write_plot_area;
-}
-
-/*
- * Initialize a pie chart.
- */
-STATIC void
-_chart_initialize_pie_chart(lxw_chart *self)
-{
-    /* Initialize the function pointers for this chart type. */
-    self->chart_group = LXW_CHART_PIE;
-    self->write_chart_type = _chart_write_pie_chart;
-    self->write_plot_area = _chart_write_pie_plot_area;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_BEST_FIT;
-}
-
-/*
- * Initialize a scatter chart.
- */
-STATIC void
-_chart_initialize_scatter_chart(lxw_chart *self)
-{
-    self->chart_group = LXW_CHART_SCATTER;
-    self->has_horiz_val_axis = LXW_FALSE;
-    self->default_cross_between = LXW_CHART_AXIS_POSITION_ON_TICK;
-    self->x_axis->is_value = LXW_TRUE;
-    self->y_axis->is_value = LXW_TRUE;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_RIGHT;
-
-    if (self->type == LXW_CHART_SCATTER_STRAIGHT
-        || self->type == LXW_CHART_SCATTER_SMOOTH) {
-
-        _chart_set_default_marker_type(self, LXW_CHART_MARKER_NONE);
-    }
-
-    /* Initialize the function pointers for this chart type. */
-    self->write_chart_type = _chart_write_scatter_chart;
-    self->write_plot_area = _chart_write_scatter_plot_area;
-}
-
-/*
- * Initialize a radar chart.
- */
-STATIC void
-_chart_initialize_radar_chart(lxw_chart *self, uint8_t type)
-{
-    if (type == LXW_CHART_RADAR)
-        _chart_set_default_marker_type(self, LXW_CHART_MARKER_NONE);
-
-    self->chart_group = LXW_CHART_RADAR;
-    self->x_axis->major_gridlines.visible = LXW_TRUE;
-    self->x_axis->is_category = LXW_TRUE;
-    self->y_axis->is_value = LXW_TRUE;
-    self->y_axis->major_tick_mark = LXW_CHART_AXIS_TICK_MARK_CROSSING;
-    self->default_label_position = LXW_CHART_LABEL_POSITION_CENTER;
-
-    /* Initialize the function pointers for this chart type. */
-    self->write_chart_type = _chart_write_radar_chart;
-    self->write_plot_area = _chart_write_plot_area;
-}
-
-/*
- * Initialize the chart specific properties.
- */
-STATIC void
-_chart_initialize(lxw_chart *self, uint8_t type)
-{
-    switch (type) {
-
-        case LXW_CHART_AREA:
-        case LXW_CHART_AREA_STACKED:
-        case LXW_CHART_AREA_STACKED_PERCENT:
-            _chart_initialize_area_chart(self, type);
-            break;
-
-        case LXW_CHART_BAR:
-        case LXW_CHART_BAR_STACKED:
-        case LXW_CHART_BAR_STACKED_PERCENT:
-            _chart_initialize_bar_chart(self, type);
-            break;
-
-        case LXW_CHART_COLUMN:
-        case LXW_CHART_COLUMN_STACKED:
-        case LXW_CHART_COLUMN_STACKED_PERCENT:
-            _chart_initialize_column_chart(self, type);
-            break;
-
-        case LXW_CHART_DOUGHNUT:
-            _chart_initialize_doughnut_chart(self);
-            break;
-
-        case LXW_CHART_LINE:
-            _chart_initialize_line_chart(self);
-            break;
-
-        case LXW_CHART_PIE:
-            _chart_initialize_pie_chart(self);
-            break;
-
-        case LXW_CHART_SCATTER:
-        case LXW_CHART_SCATTER_STRAIGHT:
-        case LXW_CHART_SCATTER_STRAIGHT_WITH_MARKERS:
-        case LXW_CHART_SCATTER_SMOOTH:
-        case LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS:
-            _chart_initialize_scatter_chart(self);
-            break;
-
-        case LXW_CHART_RADAR:
-        case LXW_CHART_RADAR_WITH_MARKERS:
-        case LXW_CHART_RADAR_FILLED:
-            _chart_initialize_radar_chart(self, type);
-            break;
-
-        default:
-            LXW_WARN_FORMAT1("workbook_add_chart(): "
-                             "unhandled chart type '%d'", type);
-    }
-}
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_chart_assemble_xml_file(lxw_chart *self)
-{
-    /* Reverse the X and Y axes for Bar charts. */
-    if (self->type == LXW_CHART_BAR || self->type == LXW_CHART_BAR_STACKED
-        || self->type == LXW_CHART_BAR_STACKED_PERCENT)
-        _chart_swap_bar_axes(self);
-
-    /* Write the XML declaration. */
-    _chart_xml_declaration(self);
-
-    /* Write the c:chartSpace element. */
-    _chart_write_chart_space(self);
-
-    /* Write the c:lang element. */
-    _chart_write_lang(self);
-
-    /* Write the c:style element. */
-    _chart_write_style(self);
-
-    /* Write the c:chart element. */
-    _chart_write_chart(self);
-
-    /* Write the c:spPr element for the chartarea formatting. */
-    _chart_write_sp_pr(self, self->chartarea_line, self->chartarea_fill,
-                       self->chartarea_pattern);
-
-    /* Write the c:printSettings element. */
-    _chart_write_print_settings(self);
-
-    lxw_xml_end_tag(self->file, "c:chartSpace");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-/*
- * Add data to a data cache in a range object, for testing only.
- */
-lxw_error
-lxw_chart_add_data_cache(lxw_series_range *range, uint8_t *data,
-                         uint16_t rows, uint8_t cols, uint8_t col)
-{
-    struct lxw_series_data_point *data_point;
-    uint16_t i;
-
-    range->ignore_cache = LXW_TRUE;
-    range->num_data_points = rows;
-
-    /* Initialize the series range data cache. */
-    for (i = 0; i < rows; i++) {
-        data_point = calloc(1, sizeof(struct lxw_series_data_point));
-        RETURN_ON_MEM_ERROR(data_point, LXW_ERROR_MEMORY_MALLOC_FAILED);
-        STAILQ_INSERT_TAIL(range->data_cache, data_point, list_pointers);
-        data_point->number = data[i * cols + col];
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Insert an image into the worksheet.
- */
-lxw_chart_series *
-chart_add_series(lxw_chart *self, const char *categories, const char *values)
-{
-    lxw_chart_series *series;
-
-    /* Scatter charts require categories and values. */
-    if (self->chart_group == LXW_CHART_SCATTER && values && !categories) {
-        LXW_WARN("chart_add_series(): scatter charts must have "
-                 "'categories' and 'values'");
-
-        return NULL;
-    }
-
-    /* Create a new object to hold the series. */
-    series = calloc(1, sizeof(lxw_chart_series));
-    GOTO_LABEL_ON_MEM_ERROR(series, mem_error);
-
-    series->categories = calloc(1, sizeof(lxw_series_range));
-    GOTO_LABEL_ON_MEM_ERROR(series->categories, mem_error);
-
-    series->values = calloc(1, sizeof(lxw_series_range));
-    GOTO_LABEL_ON_MEM_ERROR(series->values, mem_error);
-
-    series->title.range = calloc(1, sizeof(lxw_series_range));
-    GOTO_LABEL_ON_MEM_ERROR(series->title.range, mem_error);
-
-    series->x_error_bars = calloc(1, sizeof(lxw_series_error_bars));
-    GOTO_LABEL_ON_MEM_ERROR(series->x_error_bars, mem_error);
-
-    series->y_error_bars = calloc(1, sizeof(lxw_series_error_bars));
-    GOTO_LABEL_ON_MEM_ERROR(series->y_error_bars, mem_error);
-
-    if (categories) {
-        if (categories[0] == '=')
-            series->categories->formula = lxw_strdup(categories + 1);
-        else
-            series->categories->formula = lxw_strdup(categories);
-    }
-
-    if (values) {
-        if (values[0] == '=')
-            series->values->formula = lxw_strdup(values + 1);
-        else
-            series->values->formula = lxw_strdup(values);
-    }
-
-    if (_chart_init_data_cache(series->categories) != LXW_NO_ERROR)
-        goto mem_error;
-
-    if (_chart_init_data_cache(series->values) != LXW_NO_ERROR)
-        goto mem_error;
-
-    if (_chart_init_data_cache(series->title.range) != LXW_NO_ERROR)
-        goto mem_error;
-
-    if (self->type == LXW_CHART_SCATTER_SMOOTH)
-        series->smooth = LXW_TRUE;
-
-    if (self->type == LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS)
-        series->smooth = LXW_TRUE;
-
-    series->y_error_bars->chart_group = self->chart_group;
-    series->x_error_bars->chart_group = self->chart_group;
-    series->x_error_bars->is_x = LXW_TRUE;
-
-    series->default_label_position = self->default_label_position;
-
-    STAILQ_INSERT_TAIL(self->series_list, series, list_pointers);
-
-    return series;
-
-mem_error:
-    _chart_series_free(series);
-    return NULL;
-}
-
-/*
- * Set on of the 48 built-in Excel chart styles.
- */
-void
-chart_set_style(lxw_chart *self, uint8_t style_id)
-{
-    /* The default style is 2. The range is 1 - 48 */
-    if (style_id < 1 || style_id > 48)
-        style_id = 2;
-
-    self->style_id = style_id;
-}
-
-/*
- * Set a user defined name for a series.
- */
-void
-chart_series_set_name(lxw_chart_series *series, const char *name)
-{
-    if (!name)
-        return;
-
-    if (name[0] == '=')
-        series->title.range->formula = lxw_strdup(name + 1);
-    else
-        series->title.name = lxw_strdup(name);
-}
-
-/*
- * Set an axis caption, with a range instead or a formula..
- */
-void
-chart_series_set_name_range(lxw_chart_series *series, const char *sheetname,
-                            lxw_row_t row, lxw_col_t col)
-{
-    if (!sheetname) {
-        LXW_WARN("chart_series_set_name_range(): "
-                 "sheetname must be specified");
-        return;
-    }
-
-    /* Start and end row, col are the same for single cell range. */
-    _chart_set_range(series->title.range, sheetname, row, col, row, col);
-}
-
-/*
- * Set the categories range for a series.
- */
-void
-chart_series_set_categories(lxw_chart_series *series, const char *sheetname,
-                            lxw_row_t first_row, lxw_col_t first_col,
-                            lxw_row_t last_row, lxw_col_t last_col)
-{
-    if (!sheetname) {
-        LXW_WARN("chart_series_set_categories(): "
-                 "sheetname must be specified");
-        return;
-    }
-
-    _chart_set_range(series->categories, sheetname,
-                     first_row, first_col, last_row, last_col);
-}
-
-/*
- * Set the values range for a series.
- */
-void
-chart_series_set_values(lxw_chart_series *series, const char *sheetname,
-                        lxw_row_t first_row, lxw_col_t first_col,
-                        lxw_row_t last_row, lxw_col_t last_col)
-{
-    if (!sheetname) {
-        LXW_WARN("chart_series_set_values(): sheetname must be specified");
-        return;
-    }
-
-    _chart_set_range(series->values, sheetname,
-                     first_row, first_col, last_row, last_col);
-}
-
-/*
- * Set a line type for a series.
- */
-void
-chart_series_set_line(lxw_chart_series *series, lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(series->line);
-
-    series->line = _chart_convert_line_args(line);
-}
-
-/*
- * Set a fill type for a series.
- */
-void
-chart_series_set_fill(lxw_chart_series *series, lxw_chart_fill *fill)
-{
-    if (!fill)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(series->fill);
-
-    series->fill = _chart_convert_fill_args(fill);
-}
-
-/*
- * Invert the colors of a fill for a series.
- */
-void
-chart_series_set_invert_if_negative(lxw_chart_series *series)
-{
-    series->invert_if_negative = LXW_TRUE;
-}
-
-/*
- * Set a pattern type for a series.
- */
-void
-chart_series_set_pattern(lxw_chart_series *series, lxw_chart_pattern *pattern)
-{
-    if (!pattern)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(series->pattern);
-
-    series->pattern = _chart_convert_pattern_args(pattern);
-}
-
-/*
- * Set a marker type for a series.
- */
-void
-chart_series_set_marker_type(lxw_chart_series *series, uint8_t type)
-{
-    if (!series->marker) {
-        lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
-        RETURN_VOID_ON_MEM_ERROR(marker);
-        series->marker = marker;
-    }
-
-    series->marker->type = type;
-}
-
-/*
- * Set a marker size for a series.
- */
-void
-chart_series_set_marker_size(lxw_chart_series *series, uint8_t size)
-{
-    if (!series->marker) {
-        lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
-        RETURN_VOID_ON_MEM_ERROR(marker);
-        series->marker = marker;
-    }
-
-    series->marker->size = size;
-}
-
-/*
- * Set a line type for a series marker.
- */
-void
-chart_series_set_marker_line(lxw_chart_series *series, lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    if (!series->marker) {
-        lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
-        RETURN_VOID_ON_MEM_ERROR(marker);
-        series->marker = marker;
-    }
-
-    /* Free any previously allocated resource. */
-    free(series->marker->line);
-
-    series->marker->line = _chart_convert_line_args(line);
-}
-
-/*
- * Set a fill type for a series marker.
- */
-void
-chart_series_set_marker_fill(lxw_chart_series *series, lxw_chart_fill *fill)
-{
-    if (!fill)
-        return;
-
-    if (!series->marker) {
-        lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
-        RETURN_VOID_ON_MEM_ERROR(marker);
-        series->marker = marker;
-    }
-
-    /* Free any previously allocated resource. */
-    free(series->marker->fill);
-
-    series->marker->fill = _chart_convert_fill_args(fill);
-}
-
-/*
- * Set a pattern type for a series.
- */
-void
-chart_series_set_marker_pattern(lxw_chart_series *series,
-                                lxw_chart_pattern *pattern)
-{
-    if (!pattern)
-        return;
-
-    if (!series->marker) {
-        lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
-        RETURN_VOID_ON_MEM_ERROR(marker);
-        series->marker = marker;
-    }
-
-    /* Free any previously allocated resource. */
-    free(series->marker->pattern);
-
-    series->marker->pattern = _chart_convert_pattern_args(pattern);
-}
-
-/*
- * Store the horizontal page breaks on a worksheet.
- */
-lxw_error
-chart_series_set_points(lxw_chart_series *series, lxw_chart_point *points[])
-{
-    uint16_t i = 0;
-    uint16_t point_count = 0;
-
-    if (points == NULL)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    while (points[point_count])
-        point_count++;
-
-    if (point_count == 0)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    /* Free any existing resource. */
-    _chart_free_points(series);
-
-    series->points = calloc(point_count, sizeof(lxw_chart_point));
-    RETURN_ON_MEM_ERROR(series->points, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    for (i = 0; i < point_count; i++) {
-        lxw_chart_point *src_point = points[i];
-        lxw_chart_point *dst_point = &series->points[i];
-
-        dst_point->line = _chart_convert_line_args(src_point->line);
-        dst_point->fill = _chart_convert_fill_args(src_point->fill);
-        dst_point->pattern = _chart_convert_pattern_args(src_point->pattern);
-    }
-
-    series->point_count = point_count;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the smooth property for a line or scatter series.
- */
-void
-chart_series_set_smooth(lxw_chart_series *series, uint8_t smooth)
-{
-    series->smooth = smooth;
-}
-
-/*
- * Turn on default data labels for a series.
- */
-void
-chart_series_set_labels(lxw_chart_series *series)
-{
-    series->has_labels = LXW_TRUE;
-    series->show_labels_value = LXW_TRUE;
-}
-
-/*
- * Set the data labels options for a series.
- */
-void
-chart_series_set_labels_options(lxw_chart_series *series, uint8_t show_name,
-                                uint8_t show_category, uint8_t show_value)
-{
-    series->has_labels = LXW_TRUE;
-    series->show_labels_name = show_name;
-    series->show_labels_category = show_category;
-    series->show_labels_value = show_value;
-}
-
-/*
- * Set the data labels separator for a series.
- */
-void
-chart_series_set_labels_separator(lxw_chart_series *series, uint8_t separator)
-{
-    series->has_labels = LXW_TRUE;
-    series->label_separator = separator;
-}
-
-/*
- * Set the data labels position for a series.
- */
-void
-chart_series_set_labels_position(lxw_chart_series *series, uint8_t position)
-{
-    series->has_labels = LXW_TRUE;
-    series->show_labels_value = LXW_TRUE;
-
-    if (position != series->default_label_position)
-        series->label_position = position;
-}
-
-/*
- * Set the data labels position for a series.
- */
-void
-chart_series_set_labels_leader_line(lxw_chart_series *series)
-{
-    series->has_labels = LXW_TRUE;
-    series->show_labels_leader = LXW_TRUE;
-}
-
-/*
- * Turn on the data labels legend for a series.
- */
-void
-chart_series_set_labels_legend(lxw_chart_series *series)
-{
-    series->has_labels = LXW_TRUE;
-    series->show_labels_legend = LXW_TRUE;
-}
-
-/*
- * Turn on the data labels percentage for a series.
- */
-void
-chart_series_set_labels_percentage(lxw_chart_series *series)
-{
-    series->has_labels = LXW_TRUE;
-    series->show_labels_percent = LXW_TRUE;
-}
-
-/*
- * Set an data labels number format.
- */
-void
-chart_series_set_labels_num_format(lxw_chart_series *series,
-                                   const char *num_format)
-{
-    if (!num_format)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(series->label_num_format);
-
-    series->label_num_format = lxw_strdup(num_format);
-}
-
-/*
- * Set an data labels font.
- */
-void
-chart_series_set_labels_font(lxw_chart_series *series, lxw_chart_font *font)
-{
-    if (!font)
-        return;
-
-    /* Free any previously allocated resource. */
-    _chart_free_font(series->label_font);
-
-    series->label_font = _chart_convert_font_args(font);
-}
-
-/*
- * Set the trendline for a chart series.
- */
-void
-chart_series_set_trendline(lxw_chart_series *series, uint8_t type,
-                           uint8_t value)
-{
-    if (type == LXW_CHART_TRENDLINE_TYPE_POLY
-        || type == LXW_CHART_TRENDLINE_TYPE_AVERAGE) {
-
-        if (value < 2) {
-            LXW_WARN("chart_series_set_trendline(): order/period value must "
-                     "be >= 2 for Polynomial and Moving Average types");
-            return;
-        }
-
-        series->trendline_value_type = type;
-    }
-
-    series->has_trendline = LXW_TRUE;
-    series->trendline_type = type;
-    series->trendline_value = value;
-}
-
-/*
- * Set the trendline forecast for a chart series.
- */
-void
-chart_series_set_trendline_forecast(lxw_chart_series *series, double forward,
-                                    double backward)
-{
-    if (!series->has_trendline) {
-        LXW_WARN("chart_series_set_trendline_forecast(): trendline type "
-                 "must be set first using chart_series_set_trendline()");
-        return;
-    }
-
-    if (series->trendline_type == LXW_CHART_TRENDLINE_TYPE_AVERAGE) {
-        LXW_WARN("chart_series_set_trendline(): forecast isn't available "
-                 "in Excel for a Moving Average trendline");
-        return;
-    }
-
-    series->has_trendline_forecast = LXW_TRUE;
-    series->trendline_forward = forward;
-    series->trendline_backward = backward;
-}
-
-/*
- * Display the equation for a series trendline.
- */
-void
-chart_series_set_trendline_equation(lxw_chart_series *series)
-{
-    if (!series->has_trendline) {
-        LXW_WARN("chart_series_set_trendline_equation(): trendline type "
-                 "must be set first using chart_series_set_trendline()");
-        return;
-    }
-
-    if (series->trendline_type == LXW_CHART_TRENDLINE_TYPE_AVERAGE) {
-        LXW_WARN("chart_series_set_trendline_equation(): equation isn't "
-                 "available in Excel for a Moving Average trendline");
-        return;
-    }
-
-    series->has_trendline_equation = LXW_TRUE;
-}
-
-/*
- * Display the R squared value for a series trendline.
- */
-void
-chart_series_set_trendline_r_squared(lxw_chart_series *series)
-{
-    if (!series->has_trendline) {
-        LXW_WARN("chart_series_set_trendline_r_squared(): trendline type "
-                 "must be set first using chart_series_set_trendline()");
-        return;
-    }
-
-    if (series->trendline_type == LXW_CHART_TRENDLINE_TYPE_AVERAGE) {
-        LXW_WARN("chart_series_set_trendline_r_squared(): R squared isn't "
-                 "available in Excel for a Moving Average trendline");
-        return;
-    }
-
-    series->has_trendline_r_squared = LXW_TRUE;
-}
-
-/*
- * Set the trendline intercept for a chart series.
- */
-void
-chart_series_set_trendline_intercept(lxw_chart_series *series,
-                                     double intercept)
-{
-    if (!series->has_trendline) {
-        LXW_WARN("chart_series_set_trendline_intercept(): trendline type "
-                 "must be set first using chart_series_set_trendline()");
-        return;
-    }
-
-    if (series->trendline_type != LXW_CHART_TRENDLINE_TYPE_EXP
-        && series->trendline_type != LXW_CHART_TRENDLINE_TYPE_LINEAR
-        && series->trendline_type != LXW_CHART_TRENDLINE_TYPE_POLY) {
-
-        LXW_WARN("chart_series_set_trendline_intercept(): intercept is only "
-                 "available in Excel for Exponential, Linear and Polynomial "
-                 "trendline types");
-        return;
-    }
-
-    series->has_trendline_intercept = LXW_TRUE;
-    series->trendline_intercept = intercept;
-}
-
-/*
- * Set a line type for a series trendline.
- */
-void
-chart_series_set_trendline_name(lxw_chart_series *series, const char *name)
-{
-    if (!name)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(series->trendline_name);
-
-    series->trendline_name = lxw_strdup(name);
-}
-
-/*
- * Set a line type for a series trendline.
- */
-void
-chart_series_set_trendline_line(lxw_chart_series *series,
-                                lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(series->trendline_line);
-
-    series->trendline_line = _chart_convert_line_args(line);
-}
-
-/*
- * Set the X or Y error bars from a chart series.
- */
-lxw_series_error_bars *
-chart_series_get_error_bars(lxw_chart_series *series,
-                            lxw_chart_error_bar_axis axis_type)
-{
-    if (!series)
-        return NULL;
-
-    if (axis_type == LXW_CHART_ERROR_BAR_AXIS_X)
-        return series->x_error_bars;
-    else if (axis_type == LXW_CHART_ERROR_BAR_AXIS_Y)
-        return series->y_error_bars;
-    else
-        return NULL;
-}
-
-/*
- * Set the error bars and type for a chart series.
- */
-void
-chart_series_set_error_bars(lxw_series_error_bars *error_bars,
-                            uint8_t type, double value)
-{
-    if (_chart_check_error_bars(error_bars, ""))
-        return;
-
-    error_bars->type = type;
-    error_bars->value = value;
-    error_bars->has_value = LXW_TRUE;
-    error_bars->is_set = LXW_TRUE;
-
-    if (type == LXW_CHART_ERROR_BAR_TYPE_STD_ERROR)
-        error_bars->has_value = LXW_FALSE;
-}
-
-/*
- * Set the error bars direction for a chart series.
- */
-void
-chart_series_set_error_bars_direction(lxw_series_error_bars *error_bars,
-                                      uint8_t direction)
-{
-    if (_chart_check_error_bars(error_bars, "_direction"))
-        return;
-
-    error_bars->direction = direction;
-}
-
-/*
- * Set the error bars end cap type for a chart series.
- */
-void
-chart_series_set_error_bars_endcap(lxw_series_error_bars *error_bars,
-                                   uint8_t endcap)
-{
-    if (_chart_check_error_bars(error_bars, "_endcap"))
-        return;
-
-    error_bars->endcap = endcap;
-}
-
-/*
- * Set a line type for a series error bars.
- */
-void
-chart_series_set_error_bars_line(lxw_series_error_bars *error_bars,
-                                 lxw_chart_line *line)
-{
-    if (_chart_check_error_bars(error_bars, "_line"))
-        return;
-
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(error_bars->line);
-
-    error_bars->line = _chart_convert_line_args(line);
-}
-
-/*
- * Get an axis pointer from a chart.
- */
-lxw_chart_axis *
-chart_axis_get(lxw_chart *self, lxw_chart_axis_type axis_type)
-{
-    if (!self)
-        return NULL;
-
-    if (axis_type == LXW_CHART_AXIS_TYPE_X)
-        return self->x_axis;
-    else if (axis_type == LXW_CHART_AXIS_TYPE_Y)
-        return self->y_axis;
-    else
-        return NULL;
-}
-
-/*
- * Set an axis caption.
- */
-void
-chart_axis_set_name(lxw_chart_axis *axis, const char *name)
-{
-    if (!name)
-        return;
-
-    if (name[0] == '=')
-        axis->title.range->formula = lxw_strdup(name + 1);
-    else
-        axis->title.name = lxw_strdup(name);
-}
-
-/*
- * Set an axis caption, with a range instead or a formula.
- */
-void
-chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname,
-                          lxw_row_t row, lxw_col_t col)
-{
-    if (!sheetname) {
-        LXW_WARN("chart_axis_set_name_range(): sheetname must be specified");
-        return;
-    }
-
-    /* Start and end row, col are the same for single cell range. */
-    _chart_set_range(axis->title.range, sheetname, row, col, row, col);
-}
-
-/*
- * Set an axis title/name font.
- */
-void
-chart_axis_set_name_font(lxw_chart_axis *axis, lxw_chart_font *font)
-{
-    if (!font)
-        return;
-
-    /* Free any previously allocated resource. */
-    _chart_free_font(axis->title.font);
-
-    axis->title.font = _chart_convert_font_args(font);
-}
-
-/*
- * Set an axis number font.
- */
-void
-chart_axis_set_num_font(lxw_chart_axis *axis, lxw_chart_font *font)
-{
-    if (!font)
-        return;
-
-    /* Free any previously allocated resource. */
-    _chart_free_font(axis->num_font);
-
-    axis->num_font = _chart_convert_font_args(font);
-}
-
-/*
- * Set an axis number format.
- */
-void
-chart_axis_set_num_format(lxw_chart_axis *axis, const char *num_format)
-{
-    if (!num_format)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->num_format);
-
-    axis->num_format = lxw_strdup(num_format);
-}
-
-/*
- * Set a line type for an axis.
- */
-void
-chart_axis_set_line(lxw_chart_axis *axis, lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->line);
-
-    axis->line = _chart_convert_line_args(line);
-}
-
-/*
- * Set a fill type for an axis.
- */
-void
-chart_axis_set_fill(lxw_chart_axis *axis, lxw_chart_fill *fill)
-{
-    if (!fill)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->fill);
-
-    axis->fill = _chart_convert_fill_args(fill);
-}
-
-/*
- * Set a pattern type for an axis.
- */
-void
-chart_axis_set_pattern(lxw_chart_axis *axis, lxw_chart_pattern *pattern)
-{
-    if (!pattern)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->pattern);
-
-    axis->pattern = _chart_convert_pattern_args(pattern);
-}
-
-/*
- * Reverse the direction of an axis.
- */
-void
-chart_axis_set_reverse(lxw_chart_axis *axis)
-{
-    axis->reverse = LXW_TRUE;
-}
-
-/*
- * Set the axis crossing position.
- */
-void
-chart_axis_set_crossing(lxw_chart_axis *axis, double value)
-{
-    axis->has_crossing = LXW_TRUE;
-    axis->crossing = value;
-}
-
-/*
- * Set the axis crossing position as the max possible value.
- */
-void
-chart_axis_set_crossing_max(lxw_chart_axis *axis)
-{
-    axis->has_crossing = LXW_TRUE;
-    axis->crossing_max = LXW_TRUE;
-}
-
-/*
- * Turn off/hide the axis.
- */
-void
-chart_axis_off(lxw_chart_axis *axis)
-{
-    axis->hidden = LXW_TRUE;
-}
-
-/*
- * Set the category axis position.
- */
-void
-chart_axis_set_position(lxw_chart_axis *axis, uint8_t position)
-{
-    LXW_WARN_CAT_AND_DATE_AXIS_ONLY("chart_axis_set_position");
-
-    axis->position_axis = position;
-}
-
-/*
- * Set the axis label position.
- */
-void
-chart_axis_set_label_position(lxw_chart_axis *axis, uint8_t position)
-{
-    axis->label_position = position;
-}
-
-/*
- * Set the minimum value for an axis.
- */
-void
-chart_axis_set_min(lxw_chart_axis *axis, double min)
-{
-    LXW_WARN_VALUE_AND_DATE_AXIS_ONLY("chart_axis_set_min");
-
-    axis->min = min;
-    axis->has_min = LXW_TRUE;
-}
-
-/*
- * Set the maximum value for an axis.
- */
-void
-chart_axis_set_max(lxw_chart_axis *axis, double max)
-{
-    LXW_WARN_VALUE_AND_DATE_AXIS_ONLY("chart_axis_set_max");
-
-    axis->max = max;
-    axis->has_max = LXW_TRUE;
-}
-
-/*
- * Set the log base for an axis.
- */
-void
-chart_axis_set_log_base(lxw_chart_axis *axis, uint16_t log_base)
-{
-    LXW_WARN_VALUE_AXIS_ONLY("chart_axis_set_log_base");
-
-    /* Excel log range is 2-1000. */
-    if (log_base >= 2 && log_base <= 1000)
-        axis->log_base = log_base;
-}
-
-/*
- * Set the major mark for an axis.
- */
-void
-chart_axis_set_major_tick_mark(lxw_chart_axis *axis, uint8_t type)
-{
-    axis->major_tick_mark = type;
-}
-
-/*
- * Set the minor mark for an axis.
- */
-void
-chart_axis_set_minor_tick_mark(lxw_chart_axis *axis, uint8_t type)
-{
-    axis->minor_tick_mark = type;
-}
-
-/*
- * Set interval unit for a category axis.
- */
-void
-chart_axis_set_interval_unit(lxw_chart_axis *axis, uint16_t unit)
-{
-    LXW_WARN_CAT_AND_DATE_AXIS_ONLY("chart_axis_set_major_unit");
-
-    axis->interval_unit = unit;
-}
-
-/*
- * Set tick interval for a category axis.
- */
-void
-chart_axis_set_interval_tick(lxw_chart_axis *axis, uint16_t unit)
-{
-    LXW_WARN_CAT_AND_DATE_AXIS_ONLY("chart_axis_set_major_tick");
-
-    axis->interval_tick = unit;
-}
-
-/*
- * Set major unit for a value axis.
- */
-void
-chart_axis_set_major_unit(lxw_chart_axis *axis, double unit)
-{
-    LXW_WARN_VALUE_AND_DATE_AXIS_ONLY("chart_axis_set_major_unit");
-
-    axis->has_major_unit = LXW_TRUE;
-    axis->major_unit = unit;
-}
-
-/*
- * Set minor unit for a value axis.
- */
-void
-chart_axis_set_minor_unit(lxw_chart_axis *axis, double unit)
-{
-    LXW_WARN_VALUE_AND_DATE_AXIS_ONLY("chart_axis_set_minor_unit");
-
-    axis->has_minor_unit = LXW_TRUE;
-    axis->minor_unit = unit;
-}
-
-/*
- * Set the display units for a value axis.
- */
-void
-chart_axis_set_display_units(lxw_chart_axis *axis, uint8_t units)
-{
-    LXW_WARN_VALUE_AXIS_ONLY("chart_axis_set_display_units");
-
-    axis->display_units = units;
-    axis->display_units_visible = LXW_TRUE;
-}
-
-/*
- * Turn on/off the display units for a value axis.
- */
-void
-chart_axis_set_display_units_visible(lxw_chart_axis *axis, uint8_t visible)
-{
-    LXW_WARN_VALUE_AXIS_ONLY("chart_axis_set_display_units");
-
-    axis->display_units_visible = visible;
-}
-
-/*
- * Set the axis major gridlines on/off.
- */
-void
-chart_axis_major_gridlines_set_visible(lxw_chart_axis *axis, uint8_t visible)
-{
-    axis->major_gridlines.visible = visible;
-}
-
-/*
- * Set a line type for the major gridlines.
- */
-void
-chart_axis_major_gridlines_set_line(lxw_chart_axis *axis,
-                                    lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->major_gridlines.line);
-
-    axis->major_gridlines.line = _chart_convert_line_args(line);
-
-    /* If the gridline has a format it should also be visible. */
-    if (axis->major_gridlines.line)
-        axis->major_gridlines.visible = LXW_TRUE;
-}
-
-/*
- * Set the axis minor gridlines on/off.
- */
-void
-chart_axis_minor_gridlines_set_visible(lxw_chart_axis *axis, uint8_t visible)
-{
-    axis->minor_gridlines.visible = visible;
-}
-
-/*
- * Set a line type for the minor gridlines.
- */
-void
-chart_axis_minor_gridlines_set_line(lxw_chart_axis *axis,
-                                    lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(axis->minor_gridlines.line);
-
-    axis->minor_gridlines.line = _chart_convert_line_args(line);
-
-    /* If the gridline has a format it should also be visible. */
-    if (axis->minor_gridlines.line)
-        axis->minor_gridlines.visible = LXW_TRUE;
-}
-
-/*
- * Set the chart title.
- */
-void
-chart_title_set_name(lxw_chart *self, const char *name)
-{
-    if (!name)
-        return;
-
-    if (name[0] == '=')
-        self->title.range->formula = lxw_strdup(name + 1);
-    else
-        self->title.name = lxw_strdup(name);
-}
-
-/*
- * Set the chart title, with a range instead or a formula.
- */
-void
-chart_title_set_name_range(lxw_chart *self, const char *sheetname,
-                           lxw_row_t row, lxw_col_t col)
-{
-    if (!sheetname) {
-        LXW_WARN("chart_title_set_name_range(): sheetname must be specified");
-        return;
-    }
-
-    /* Start and end row, col are the same for single cell range. */
-    _chart_set_range(self->title.range, sheetname, row, col, row, col);
-}
-
-/*
- * Set the chart title font.
- */
-void
-chart_title_set_name_font(lxw_chart *self, lxw_chart_font *font)
-{
-    /* Free any previously allocated resource. */
-    _chart_free_font(self->title.font);
-
-    self->title.font = _chart_convert_font_args(font);
-}
-
-/*
- * Turn off the chart title.
- */
-void
-chart_title_off(lxw_chart *self)
-{
-    self->title.off = LXW_TRUE;
-}
-
-/*
- * Set the chart legend position.
- */
-void
-chart_legend_set_position(lxw_chart *self, uint8_t position)
-{
-    self->legend.position = position;
-}
-
-/*
- * Set the legend font.
- */
-void
-chart_legend_set_font(lxw_chart *self, lxw_chart_font *font)
-{
-    /* Free any previously allocated resource. */
-    _chart_free_font(self->legend.font);
-
-    self->legend.font = _chart_convert_font_args(font);
-}
-
-/*
- * Remove one or more series from the the legend.
- */
-lxw_error
-chart_legend_delete_series(lxw_chart *self, int16_t delete_series[])
-{
-    uint16_t count = 0;
-
-    if (delete_series == NULL)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    while (delete_series[count] >= 0)
-        count++;
-
-    if (count == 0)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    /* The maximum number of series in a chart is 255. */
-    if (count > 255)
-        count = 255;
-
-    self->delete_series = calloc(count, sizeof(int16_t));
-    RETURN_ON_MEM_ERROR(self->delete_series, LXW_ERROR_MEMORY_MALLOC_FAILED);
-    memcpy(self->delete_series, delete_series, count * sizeof(int16_t));
-    self->delete_series_count = count;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set a line type for the chartarea.
- */
-void
-chart_chartarea_set_line(lxw_chart *self, lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(self->chartarea_line);
-
-    self->chartarea_line = _chart_convert_line_args(line);
-}
-
-/*
- * Set a fill type for the chartarea.
- */
-void
-chart_chartarea_set_fill(lxw_chart *self, lxw_chart_fill *fill)
-{
-    if (!fill)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(self->chartarea_fill);
-
-    self->chartarea_fill = _chart_convert_fill_args(fill);
-}
-
-/*
- * Set a pattern type for the chartarea.
- */
-void
-chart_chartarea_set_pattern(lxw_chart *self, lxw_chart_pattern *pattern)
-{
-    if (!pattern)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(self->chartarea_pattern);
-
-    self->chartarea_pattern = _chart_convert_pattern_args(pattern);
-}
-
-/*
- * Set a line type for the plotarea.
- */
-void
-chart_plotarea_set_line(lxw_chart *self, lxw_chart_line *line)
-{
-    if (!line)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(self->plotarea_line);
-
-    self->plotarea_line = _chart_convert_line_args(line);
-}
-
-/*
- * Set a fill type for the plotarea.
- */
-void
-chart_plotarea_set_fill(lxw_chart *self, lxw_chart_fill *fill)
-{
-    if (!fill)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(self->plotarea_fill);
-
-    self->plotarea_fill = _chart_convert_fill_args(fill);
-}
-
-/*
- * Set a pattern type for the plotarea.
- */
-void
-chart_plotarea_set_pattern(lxw_chart *self, lxw_chart_pattern *pattern)
-{
-    if (!pattern)
-        return;
-
-    /* Free any previously allocated resource. */
-    free(self->plotarea_pattern);
-
-    self->plotarea_pattern = _chart_convert_pattern_args(pattern);
-}
-
-/*
- * Turn on the chart data table.
- */
-void
-chart_set_table(lxw_chart *self)
-{
-    self->has_table = LXW_TRUE;
-    self->has_table_horizontal = LXW_TRUE;
-    self->has_table_vertical = LXW_TRUE;
-    self->has_table_outline = LXW_TRUE;
-    self->has_table_legend_keys = LXW_FALSE;
-}
-
-/*
- * Set the options for the chart data table grid.
- */
-void
-chart_set_table_grid(lxw_chart *self, uint8_t horizontal, uint8_t vertical,
-                     uint8_t outline, uint8_t legend_keys)
-{
-    self->has_table = LXW_TRUE;
-    self->has_table_horizontal = horizontal;
-    self->has_table_vertical = vertical;
-    self->has_table_outline = outline;
-    self->has_table_legend_keys = legend_keys;
-}
-
-/*
- * Set the font for the chart data table grid.
- */
-void
-chart_set_table_font(lxw_chart *self, lxw_chart_font *font)
-{
-    self->has_table = LXW_TRUE;
-
-    /* Free any previously allocated resource. */
-    _chart_free_font(self->table_font);
-
-    self->table_font = _chart_convert_font_args(font);
-}
-
-/*
- * Turn on up-down bars for the chart.
- */
-void
-chart_set_up_down_bars(lxw_chart *self)
-{
-    self->has_up_down_bars = LXW_TRUE;
-}
-
-/*
- * Turn on up-down bars for the chart, with formatting.
- */
-void
-chart_set_up_down_bars_format(lxw_chart *self, lxw_chart_line *up_bar_line,
-                              lxw_chart_fill *up_bar_fill,
-                              lxw_chart_line *down_bar_line,
-                              lxw_chart_fill *down_bar_fill)
-{
-    self->has_up_down_bars = LXW_TRUE;
-
-    /* Free any previously allocated resource. */
-    free(self->up_bar_line);
-    free(self->up_bar_fill);
-    free(self->down_bar_line);
-    free(self->down_bar_fill);
-
-    self->up_bar_line = _chart_convert_line_args(up_bar_line);
-    self->up_bar_fill = _chart_convert_fill_args(up_bar_fill);
-    self->down_bar_line = _chart_convert_line_args(down_bar_line);
-    self->down_bar_fill = _chart_convert_fill_args(down_bar_fill);
-}
-
-/*
- * Turn on drop lines for the chart.
- */
-void
-chart_set_drop_lines(lxw_chart *self, lxw_chart_line *line)
-{
-    /* Free any previously allocated resource. */
-    free(self->drop_lines_line);
-
-    self->has_drop_lines = LXW_TRUE;
-    self->drop_lines_line = _chart_convert_line_args(line);
-}
-
-/*
- * Turn on high_low lines for the chart.
- */
-void
-chart_set_high_low_lines(lxw_chart *self, lxw_chart_line *line)
-{
-    /* Free any previously allocated resource. */
-    free(self->high_low_lines_line);
-
-    self->has_high_low_lines = LXW_TRUE;
-    self->high_low_lines_line = _chart_convert_line_args(line);
-}
-
-/*
- * Set the Bar/Column overlap for all data series.
- */
-void
-chart_set_series_overlap(lxw_chart *self, int8_t overlap)
-{
-    if (overlap >= -100 && overlap <= 100)
-        self->overlap_y1 = overlap;
-    else
-        LXW_WARN_FORMAT1("chart_set_series_overlap(): Chart series overlap "
-                         "'%d' outside Excel range: -100 <= overlap <= 100",
-                         overlap);
-}
-
-/*
- * Set the option for displaying blank data in a chart.
- */
-void
-chart_show_blanks_as(lxw_chart *self, uint8_t option)
-{
-    self->show_blanks_as = option;
-}
-
-/*
- * Display data on charts from hidden rows or columns.
- */
-void
-chart_show_hidden_data(lxw_chart *self)
-{
-    self->show_hidden_data = LXW_TRUE;
-}
-
-/*
- * Set the Bar/Column gap for all data series.
- */
-void
-chart_set_series_gap(lxw_chart *self, uint16_t gap)
-{
-    if (gap <= 500)
-        self->gap_y1 = gap;
-    else
-        LXW_WARN_FORMAT1("chart_set_series_gap(): Chart series gap '%d' "
-                         "outside Excel range: 0 <= gap <= 500", gap);
-}
-
-/*
- * Set the Pie/Doughnut chart rotation: the angle of the first slice.
- */
-void
-chart_set_rotation(lxw_chart *self, uint16_t rotation)
-{
-    if (rotation <= 360)
-        self->rotation = rotation;
-    else
-        LXW_WARN_FORMAT1("chart_set_rotation(): Chart rotation '%d' outside "
-                         "Excel range: 0 <= rotation <= 360", rotation);
-}
-
-/*
- * Set the Doughnut chart hole size.
- */
-void
-chart_set_hole_size(lxw_chart *self, uint8_t size)
-{
-    if (size >= 10 && size <= 90)
-        self->hole_size = size;
-    else
-        LXW_WARN_FORMAT1("chart_set_hole_size(): Hole size '%d' outside "
-                         "Excel range: 10 <= size <= 90", size);
-}

+ 0 - 345
library/src/content_types.c

@@ -1,345 +0,0 @@
-/*****************************************************************************
- * content_types - A library for creating Excel XLSX content_types files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/content_types.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new content_types object.
- */
-lxw_content_types *
-lxw_content_types_new()
-{
-    lxw_content_types *content_types = calloc(1, sizeof(lxw_content_types));
-    GOTO_LABEL_ON_MEM_ERROR(content_types, mem_error);
-
-    content_types->default_types = calloc(1, sizeof(struct lxw_tuples));
-    GOTO_LABEL_ON_MEM_ERROR(content_types->default_types, mem_error);
-    STAILQ_INIT(content_types->default_types);
-
-    content_types->overrides = calloc(1, sizeof(struct lxw_tuples));
-    GOTO_LABEL_ON_MEM_ERROR(content_types->overrides, mem_error);
-    STAILQ_INIT(content_types->overrides);
-
-    lxw_ct_add_default(content_types, "rels",
-                       LXW_APP_PACKAGE "relationships+xml");
-    lxw_ct_add_default(content_types, "xml", "application/xml");
-
-    lxw_ct_add_override(content_types, "/docProps/app.xml",
-                        LXW_APP_DOCUMENT "extended-properties+xml");
-    lxw_ct_add_override(content_types, "/docProps/core.xml",
-                        LXW_APP_PACKAGE "core-properties+xml");
-    lxw_ct_add_override(content_types, "/xl/styles.xml",
-                        LXW_APP_DOCUMENT "spreadsheetml.styles+xml");
-    lxw_ct_add_override(content_types, "/xl/theme/theme1.xml",
-                        LXW_APP_DOCUMENT "theme+xml");
-    lxw_ct_add_override(content_types, "/xl/workbook.xml",
-                        LXW_APP_DOCUMENT "spreadsheetml.sheet.main+xml");
-
-    return content_types;
-
-mem_error:
-    lxw_content_types_free(content_types);
-    return NULL;
-}
-
-/*
- * Free a content_types object.
- */
-void
-lxw_content_types_free(lxw_content_types *content_types)
-{
-    lxw_tuple *default_type;
-    lxw_tuple *override;
-
-    if (!content_types)
-        return;
-
-    if (content_types->default_types) {
-        while (!STAILQ_EMPTY(content_types->default_types)) {
-            default_type = STAILQ_FIRST(content_types->default_types);
-            STAILQ_REMOVE_HEAD(content_types->default_types, list_pointers);
-            free(default_type->key);
-            free(default_type->value);
-            free(default_type);
-        }
-        free(content_types->default_types);
-    }
-
-    if (content_types->overrides) {
-        while (!STAILQ_EMPTY(content_types->overrides)) {
-            override = STAILQ_FIRST(content_types->overrides);
-            STAILQ_REMOVE_HEAD(content_types->overrides, list_pointers);
-            free(override->key);
-            free(override->value);
-            free(override);
-        }
-        free(content_types->overrides);
-    }
-
-    free(content_types);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_content_types_xml_declaration(lxw_content_types *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <Types> element.
- */
-STATIC void
-_write_types(lxw_content_types *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", LXW_SCHEMA_CONTENT);
-
-    lxw_xml_start_tag(self->file, "Types", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <Default> element.
- */
-STATIC void
-_write_default(lxw_content_types *self, const char *ext, const char *type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("Extension", ext);
-    LXW_PUSH_ATTRIBUTES_STR("ContentType", type);
-
-    lxw_xml_empty_tag(self->file, "Default", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <Override> element.
- */
-STATIC void
-_write_override(lxw_content_types *self, const char *part_name,
-                const char *type)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("PartName", part_name);
-    LXW_PUSH_ATTRIBUTES_STR("ContentType", type);
-
-    lxw_xml_empty_tag(self->file, "Override", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Write out all of the <Default> types.
- */
-STATIC void
-_write_defaults(lxw_content_types *self)
-{
-    lxw_tuple *tuple;
-
-    STAILQ_FOREACH(tuple, self->default_types, list_pointers) {
-        _write_default(self, tuple->key, tuple->value);
-    }
-}
-
-/*
- * Write out all of the <Override> types.
- */
-STATIC void
-_write_overrides(lxw_content_types *self)
-{
-    lxw_tuple *tuple;
-
-    STAILQ_FOREACH(tuple, self->overrides, list_pointers) {
-        _write_override(self, tuple->key, tuple->value);
-    }
-}
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_content_types_assemble_xml_file(lxw_content_types *self)
-{
-    /* Write the XML declaration. */
-    _content_types_xml_declaration(self);
-
-    _write_types(self);
-    _write_defaults(self);
-    _write_overrides(self);
-
-    /* Close the content_types tag. */
-    lxw_xml_end_tag(self->file, "Types");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-/*
- * Add elements to the ContentTypes defaults.
- */
-void
-lxw_ct_add_default(lxw_content_types *self, const char *key,
-                   const char *value)
-{
-    lxw_tuple *tuple;
-
-    if (!key || !value)
-        return;
-
-    tuple = calloc(1, sizeof(lxw_tuple));
-    GOTO_LABEL_ON_MEM_ERROR(tuple, mem_error);
-
-    tuple->key = lxw_strdup(key);
-    GOTO_LABEL_ON_MEM_ERROR(tuple->key, mem_error);
-
-    tuple->value = lxw_strdup(value);
-    GOTO_LABEL_ON_MEM_ERROR(tuple->value, mem_error);
-
-    STAILQ_INSERT_TAIL(self->default_types, tuple, list_pointers);
-
-    return;
-
-mem_error:
-    if (tuple) {
-        free(tuple->key);
-        free(tuple->value);
-        free(tuple);
-    }
-}
-
-/*
- * Add elements to the ContentTypes overrides.
- */
-void
-lxw_ct_add_override(lxw_content_types *self, const char *key,
-                    const char *value)
-{
-    lxw_tuple *tuple;
-
-    if (!key || !value)
-        return;
-
-    tuple = calloc(1, sizeof(lxw_tuple));
-    GOTO_LABEL_ON_MEM_ERROR(tuple, mem_error);
-
-    tuple->key = lxw_strdup(key);
-    GOTO_LABEL_ON_MEM_ERROR(tuple->key, mem_error);
-
-    tuple->value = lxw_strdup(value);
-    GOTO_LABEL_ON_MEM_ERROR(tuple->value, mem_error);
-
-    STAILQ_INSERT_TAIL(self->overrides, tuple, list_pointers);
-
-    return;
-
-mem_error:
-    if (tuple) {
-        free(tuple->key);
-        free(tuple->value);
-        free(tuple);
-    }
-}
-
-/*
- * Add the name of a worksheet to the ContentTypes overrides.
- */
-void
-lxw_ct_add_worksheet_name(lxw_content_types *self, const char *name)
-{
-    lxw_ct_add_override(self, name,
-                        LXW_APP_DOCUMENT "spreadsheetml.worksheet+xml");
-}
-
-/*
- * Add the name of a chart to the ContentTypes overrides.
- */
-void
-lxw_ct_add_chart_name(lxw_content_types *self, const char *name)
-{
-    lxw_ct_add_override(self, name, LXW_APP_DOCUMENT "drawingml.chart+xml");
-}
-
-/*
- * Add the name of a drawing to the ContentTypes overrides.
- */
-void
-lxw_ct_add_drawing_name(lxw_content_types *self, const char *name)
-{
-    lxw_ct_add_override(self, name, LXW_APP_DOCUMENT "drawing+xml");
-}
-
-/*
- * Add the sharedStrings link to the ContentTypes overrides.
- */
-void
-lxw_ct_add_shared_strings(lxw_content_types *self)
-{
-    lxw_ct_add_override(self, "/xl/sharedStrings.xml",
-                        LXW_APP_DOCUMENT "spreadsheetml.sharedStrings+xml");
-}
-
-/*
- * Add the calcChain link to the ContentTypes overrides.
- */
-void
-lxw_ct_add_calc_chain(lxw_content_types *self)
-{
-    lxw_ct_add_override(self, "/xl/calcChain.xml",
-                        LXW_APP_DOCUMENT "spreadsheetml.calcChain+xml");
-}
-
-/*
- * Add the custom properties to the ContentTypes overrides.
- */
-void
-lxw_ct_add_custom_properties(lxw_content_types *self)
-{
-    lxw_ct_add_override(self, "/docProps/custom.xml",
-                        LXW_APP_DOCUMENT "custom-properties+xml");
-}

+ 0 - 293
library/src/core.c

@@ -1,293 +0,0 @@
-/*****************************************************************************
- * core - A library for creating Excel XLSX core files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/core.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new core object.
- */
-lxw_core *
-lxw_core_new()
-{
-    lxw_core *core = calloc(1, sizeof(lxw_core));
-    GOTO_LABEL_ON_MEM_ERROR(core, mem_error);
-
-    return core;
-
-mem_error:
-    lxw_core_free(core);
-    return NULL;
-}
-
-/*
- * Free a core object.
- */
-void
-lxw_core_free(lxw_core *core)
-{
-    if (!core)
-        return;
-
-    free(core);
-}
-
-/*
- * Convert a time_t struct to a ISO 8601 style "2010-01-01T00:00:00Z" date.
- */
-static void
-_datetime_to_iso8601_date(time_t *timer, char *str, size_t size)
-{
-    struct tm *tmp_datetime;
-    time_t current_time = time(NULL);
-
-    if (*timer)
-        tmp_datetime = gmtime(timer);
-    else
-        tmp_datetime = gmtime(&current_time);
-
-    strftime(str, size - 1, "%Y-%m-%dT%H:%M:%SZ", tmp_datetime);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_core_xml_declaration(lxw_core *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <cp:coreProperties> element.
- */
-STATIC void
-_write_cp_core_properties(lxw_core *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:cp",
-                            "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:dc", "http://purl.org/dc/elements/1.1/");
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:dcterms", "http://purl.org/dc/terms/");
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:dcmitype", "http://purl.org/dc/dcmitype/");
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:xsi",
-                            "http://www.w3.org/2001/XMLSchema-instance");
-
-    lxw_xml_start_tag(self->file, "cp:coreProperties", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <dc:creator> element.
- */
-STATIC void
-_write_dc_creator(lxw_core *self)
-{
-    if (self->properties->author) {
-        lxw_xml_data_element(self->file, "dc:creator",
-                             self->properties->author, NULL);
-    }
-    else {
-        lxw_xml_data_element(self->file, "dc:creator", "", NULL);
-    }
-}
-
-/*
- * Write the <cp:lastModifiedBy> element.
- */
-STATIC void
-_write_cp_last_modified_by(lxw_core *self)
-{
-    if (self->properties->author) {
-        lxw_xml_data_element(self->file, "cp:lastModifiedBy",
-                             self->properties->author, NULL);
-    }
-    else {
-        lxw_xml_data_element(self->file, "cp:lastModifiedBy", "", NULL);
-    }
-}
-
-/*
- * Write the <dcterms:created> element.
- */
-STATIC void
-_write_dcterms_created(lxw_core *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char datetime[LXW_ATTR_32];
-
-    _datetime_to_iso8601_date(&self->properties->created, datetime,
-                              LXW_ATTR_32);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xsi:type", "dcterms:W3CDTF");
-
-    lxw_xml_data_element(self->file, "dcterms:created", datetime,
-                         &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <dcterms:modified> element.
- */
-STATIC void
-_write_dcterms_modified(lxw_core *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char datetime[LXW_ATTR_32];
-
-    _datetime_to_iso8601_date(&self->properties->created, datetime,
-                              LXW_ATTR_32);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xsi:type", "dcterms:W3CDTF");
-
-    lxw_xml_data_element(self->file, "dcterms:modified", datetime,
-                         &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <dc:title> element.
- */
-STATIC void
-_write_dc_title(lxw_core *self)
-{
-    if (!self->properties->title)
-        return;
-
-    lxw_xml_data_element(self->file, "dc:title", self->properties->title,
-                         NULL);
-}
-
-/*
- * Write the <dc:subject> element.
- */
-STATIC void
-_write_dc_subject(lxw_core *self)
-{
-    if (!self->properties->subject)
-        return;
-
-    lxw_xml_data_element(self->file, "dc:subject", self->properties->subject,
-                         NULL);
-}
-
-/*
- * Write the <cp:keywords> element.
- */
-STATIC void
-_write_cp_keywords(lxw_core *self)
-{
-    if (!self->properties->keywords)
-        return;
-
-    lxw_xml_data_element(self->file, "cp:keywords",
-                         self->properties->keywords, NULL);
-}
-
-/*
- * Write the <dc:description> element.
- */
-STATIC void
-_write_dc_description(lxw_core *self)
-{
-    if (!self->properties->comments)
-        return;
-
-    lxw_xml_data_element(self->file, "dc:description",
-                         self->properties->comments, NULL);
-}
-
-/*
- * Write the <cp:category> element.
- */
-STATIC void
-_write_cp_category(lxw_core *self)
-{
-    if (!self->properties->category)
-        return;
-
-    lxw_xml_data_element(self->file, "cp:category",
-                         self->properties->category, NULL);
-}
-
-/*
- * Write the <cp:contentStatus> element.
- */
-STATIC void
-_write_cp_content_status(lxw_core *self)
-{
-    if (!self->properties->status)
-        return;
-
-    lxw_xml_data_element(self->file, "cp:contentStatus",
-                         self->properties->status, NULL);
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_core_assemble_xml_file(lxw_core *self)
-{
-    /* Write the XML declaration. */
-    _core_xml_declaration(self);
-
-    _write_cp_core_properties(self);
-    _write_dc_title(self);
-    _write_dc_subject(self);
-    _write_dc_creator(self);
-    _write_cp_keywords(self);
-    _write_dc_description(self);
-    _write_cp_last_modified_by(self);
-    _write_dcterms_created(self);
-    _write_dcterms_modified(self);
-    _write_cp_category(self);
-    _write_cp_content_status(self);
-
-    lxw_xml_end_tag(self->file, "cp:coreProperties");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/

+ 0 - 224
library/src/custom.c

@@ -1,224 +0,0 @@
-/*****************************************************************************
- * custom - A library for creating Excel custom property files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/custom.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new custom object.
- */
-lxw_custom *
-lxw_custom_new()
-{
-    lxw_custom *custom = calloc(1, sizeof(lxw_custom));
-    GOTO_LABEL_ON_MEM_ERROR(custom, mem_error);
-
-    return custom;
-
-mem_error:
-    lxw_custom_free(custom);
-    return NULL;
-}
-
-/*
- * Free a custom object.
- */
-void
-lxw_custom_free(lxw_custom *custom)
-{
-    if (!custom)
-        return;
-
-    free(custom);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_custom_xml_declaration(lxw_custom *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <vt:lpwstr> element.
- */
-STATIC void
-_chart_write_vt_lpwstr(lxw_custom *self, char *value)
-{
-    lxw_xml_data_element(self->file, "vt:lpwstr", value, NULL);
-}
-
-/*
- * Write the <vt:r8> element.
- */
-STATIC void
-_chart_write_vt_r_8(lxw_custom *self, double value)
-{
-    char data[LXW_ATTR_32];
-
-    lxw_sprintf_dbl(data, value);
-
-    lxw_xml_data_element(self->file, "vt:r8", data, NULL);
-}
-
-/*
- * Write the <vt:i4> element.
- */
-STATIC void
-_custom_write_vt_i_4(lxw_custom *self, int32_t value)
-{
-    char data[LXW_ATTR_32];
-
-    lxw_snprintf(data, LXW_ATTR_32, "%d", value);
-
-    lxw_xml_data_element(self->file, "vt:i4", data, NULL);
-}
-
-/*
- * Write the <vt:bool> element.
- */
-STATIC void
-_custom_write_vt_bool(lxw_custom *self, uint8_t value)
-{
-    if (value)
-        lxw_xml_data_element(self->file, "vt:bool", "true", NULL);
-    else
-        lxw_xml_data_element(self->file, "vt:bool", "false", NULL);
-}
-
-/*
- * Write the <vt:filetime> element.
- */
-STATIC void
-_custom_write_vt_filetime(lxw_custom *self, lxw_datetime *datetime)
-{
-    char data[LXW_DATETIME_LENGTH];
-
-    lxw_snprintf(data, LXW_DATETIME_LENGTH, "%4d-%02d-%02dT%02d:%02d:%02dZ",
-                 datetime->year, datetime->month, datetime->day,
-                 datetime->hour, datetime->min, (int) datetime->sec);
-
-    lxw_xml_data_element(self->file, "vt:filetime", data, NULL);
-}
-
-/*
- * Write the <property> element.
- */
-STATIC void
-_chart_write_custom_property(lxw_custom *self,
-                             lxw_custom_property *custom_property)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char fmtid[] = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}";
-
-    self->pid++;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("fmtid", fmtid);
-    LXW_PUSH_ATTRIBUTES_INT("pid", self->pid + 1);
-    LXW_PUSH_ATTRIBUTES_STR("name", custom_property->name);
-
-    lxw_xml_start_tag(self->file, "property", &attributes);
-
-    if (custom_property->type == LXW_CUSTOM_STRING) {
-        /* Write the vt:lpwstr element. */
-        _chart_write_vt_lpwstr(self, custom_property->u.string);
-    }
-    else if (custom_property->type == LXW_CUSTOM_DOUBLE) {
-        /* Write the vt:r8 element. */
-        _chart_write_vt_r_8(self, custom_property->u.number);
-    }
-    else if (custom_property->type == LXW_CUSTOM_INTEGER) {
-        /* Write the vt:i4 element. */
-        _custom_write_vt_i_4(self, custom_property->u.integer);
-    }
-    else if (custom_property->type == LXW_CUSTOM_BOOLEAN) {
-        /* Write the vt:bool element. */
-        _custom_write_vt_bool(self, custom_property->u.boolean);
-    }
-    else if (custom_property->type == LXW_CUSTOM_DATETIME) {
-        /* Write the vt:filetime element. */
-        _custom_write_vt_filetime(self, &custom_property->u.datetime);
-    }
-
-    lxw_xml_end_tag(self->file, "property");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <Properties> element.
- */
-STATIC void
-_write_custom_properties(lxw_custom *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns[] = LXW_SCHEMA_OFFICEDOC "/custom-properties";
-    char xmlns_vt[] = LXW_SCHEMA_OFFICEDOC "/docPropsVTypes";
-    lxw_custom_property *custom_property;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:vt", xmlns_vt);
-
-    lxw_xml_start_tag(self->file, "Properties", &attributes);
-
-    STAILQ_FOREACH(custom_property, self->custom_properties, list_pointers) {
-        _chart_write_custom_property(self, custom_property);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_custom_assemble_xml_file(lxw_custom *self)
-{
-    /* Write the XML declaration. */
-    _custom_xml_declaration(self);
-
-    _write_custom_properties(self);
-
-    lxw_xml_end_tag(self->file, "Properties");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/

+ 0 - 746
library/src/drawing.c

@@ -1,746 +0,0 @@
-/*****************************************************************************
- * drawing - A library for creating Excel XLSX drawing files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/common.h"
-#include "xlsxwriter/drawing.h"
-#include "xlsxwriter/utility.h"
-
-#define LXW_OBJ_NAME_LENGTH 14  /* "Picture 65536", or "Chart 65536" */
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new drawing collection.
- */
-lxw_drawing *
-lxw_drawing_new()
-{
-    lxw_drawing *drawing = calloc(1, sizeof(lxw_drawing));
-    GOTO_LABEL_ON_MEM_ERROR(drawing, mem_error);
-
-    drawing->drawing_objects = calloc(1, sizeof(struct lxw_drawing_objects));
-    GOTO_LABEL_ON_MEM_ERROR(drawing->drawing_objects, mem_error);
-
-    STAILQ_INIT(drawing->drawing_objects);
-
-    return drawing;
-
-mem_error:
-    lxw_drawing_free(drawing);
-    return NULL;
-}
-
-/*
- * Free a drawing object.
- */
-void
-lxw_free_drawing_object(lxw_drawing_object *drawing_object)
-{
-    if (!drawing_object)
-        return;
-
-    free(drawing_object->description);
-    free(drawing_object->url);
-    free(drawing_object->tip);
-
-    free(drawing_object);
-}
-
-/*
- * Free a drawing collection.
- */
-void
-lxw_drawing_free(lxw_drawing *drawing)
-{
-    lxw_drawing_object *drawing_object;
-
-    if (!drawing)
-        return;
-
-    if (drawing->drawing_objects) {
-        while (!STAILQ_EMPTY(drawing->drawing_objects)) {
-            drawing_object = STAILQ_FIRST(drawing->drawing_objects);
-            STAILQ_REMOVE_HEAD(drawing->drawing_objects, list_pointers);
-            lxw_free_drawing_object(drawing_object);
-        }
-
-        free(drawing->drawing_objects);
-    }
-
-    free(drawing);
-}
-
-/*
- * Add a drawing object to the drawing collection.
- */
-void
-lxw_add_drawing_object(lxw_drawing *drawing,
-                       lxw_drawing_object *drawing_object)
-{
-    STAILQ_INSERT_TAIL(drawing->drawing_objects, drawing_object,
-                       list_pointers);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_drawing_xml_declaration(lxw_drawing *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <xdr:wsDr> element.
- */
-STATIC void
-_write_drawing_workspace(lxw_drawing *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns_xdr[] = LXW_SCHEMA_DRAWING "/spreadsheetDrawing";
-    char xmlns_a[] = LXW_SCHEMA_DRAWING "/main";
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:xdr", xmlns_xdr);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:a", xmlns_a);
-
-    lxw_xml_start_tag(self->file, "xdr:wsDr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xdr:col> element.
- */
-STATIC void
-_drawing_write_col(lxw_drawing *self, char *data)
-{
-    lxw_xml_data_element(self->file, "xdr:col", data, NULL);
-}
-
-/*
- * Write the <xdr:colOff> element.
- */
-STATIC void
-_drawing_write_col_off(lxw_drawing *self, char *data)
-{
-    lxw_xml_data_element(self->file, "xdr:colOff", data, NULL);
-}
-
-/*
- * Write the <xdr:row> element.
- */
-STATIC void
-_drawing_write_row(lxw_drawing *self, char *data)
-{
-    lxw_xml_data_element(self->file, "xdr:row", data, NULL);
-}
-
-/*
- * Write the <xdr:rowOff> element.
- */
-STATIC void
-_drawing_write_row_off(lxw_drawing *self, char *data)
-{
-    lxw_xml_data_element(self->file, "xdr:rowOff", data, NULL);
-}
-
-/*
- * Write the <xdr:from> element.
- */
-STATIC void
-_drawing_write_from(lxw_drawing *self, lxw_drawing_coords *coords)
-{
-    char data[LXW_UINT32_T_LENGTH];
-
-    lxw_xml_start_tag(self->file, "xdr:from", NULL);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u", coords->col);
-    _drawing_write_col(self, data);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u",
-                 (uint32_t) coords->col_offset);
-    _drawing_write_col_off(self, data);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u", coords->row);
-    _drawing_write_row(self, data);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u",
-                 (uint32_t) coords->row_offset);
-    _drawing_write_row_off(self, data);
-
-    lxw_xml_end_tag(self->file, "xdr:from");
-}
-
-/*
- * Write the <xdr:to> element.
- */
-STATIC void
-_drawing_write_to(lxw_drawing *self, lxw_drawing_coords *coords)
-{
-    char data[LXW_UINT32_T_LENGTH];
-
-    lxw_xml_start_tag(self->file, "xdr:to", NULL);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u", coords->col);
-    _drawing_write_col(self, data);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u",
-                 (uint32_t) coords->col_offset);
-    _drawing_write_col_off(self, data);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u", coords->row);
-    _drawing_write_row(self, data);
-
-    lxw_snprintf(data, LXW_UINT32_T_LENGTH, "%u",
-                 (uint32_t) coords->row_offset);
-    _drawing_write_row_off(self, data);
-
-    lxw_xml_end_tag(self->file, "xdr:to");
-}
-
-/*
- * Write the <xdr:cNvPr> element.
- */
-STATIC void
-_drawing_write_c_nv_pr(lxw_drawing *self, char *object_name, uint16_t index,
-                       lxw_drawing_object *drawing_object)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    char name[LXW_OBJ_NAME_LENGTH];
-    lxw_snprintf(name, LXW_OBJ_NAME_LENGTH, "%s %d", object_name, index);
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_INT("id", index + 1);
-    LXW_PUSH_ATTRIBUTES_STR("name", name);
-
-    if (drawing_object)
-        LXW_PUSH_ATTRIBUTES_STR("descr", drawing_object->description);
-
-    lxw_xml_empty_tag(self->file, "xdr:cNvPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:picLocks> element.
- */
-STATIC void
-_drawing_write_a_pic_locks(lxw_drawing *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("noChangeAspect", "1");
-
-    lxw_xml_empty_tag(self->file, "a:picLocks", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xdr:cNvPicPr> element.
- */
-STATIC void
-_drawing_write_c_nv_pic_pr(lxw_drawing *self)
-{
-    lxw_xml_start_tag(self->file, "xdr:cNvPicPr", NULL);
-
-    /* Write the a:picLocks element. */
-    _drawing_write_a_pic_locks(self);
-
-    lxw_xml_end_tag(self->file, "xdr:cNvPicPr");
-}
-
-/*
- * Write the <xdr:nvPicPr> element.
- */
-STATIC void
-_drawing_write_nv_pic_pr(lxw_drawing *self, uint16_t index,
-                         lxw_drawing_object *drawing_object)
-{
-    lxw_xml_start_tag(self->file, "xdr:nvPicPr", NULL);
-
-    /* Write the xdr:cNvPr element. */
-    _drawing_write_c_nv_pr(self, "Picture", index, drawing_object);
-
-    /* Write the xdr:cNvPicPr element. */
-    _drawing_write_c_nv_pic_pr(self);
-
-    lxw_xml_end_tag(self->file, "xdr:nvPicPr");
-}
-
-/*
- * Write the <a:blip> element.
- */
-STATIC void
-_drawing_write_a_blip(lxw_drawing *self, uint16_t index)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns_r[] = LXW_SCHEMA_OFFICEDOC "/relationships";
-    char r_id[LXW_MAX_ATTRIBUTE_LENGTH];
-
-    lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", index);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
-    LXW_PUSH_ATTRIBUTES_STR("r:embed", r_id);
-
-    lxw_xml_empty_tag(self->file, "a:blip", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:fillRect> element.
- */
-STATIC void
-_drawing_write_a_fill_rect(lxw_drawing *self)
-{
-    lxw_xml_empty_tag(self->file, "a:fillRect", NULL);
-}
-
-/*
- * Write the <a:stretch> element.
- */
-STATIC void
-_drawing_write_a_stretch(lxw_drawing *self)
-{
-    lxw_xml_start_tag(self->file, "a:stretch", NULL);
-
-    /* Write the a:fillRect element. */
-    _drawing_write_a_fill_rect(self);
-
-    lxw_xml_end_tag(self->file, "a:stretch");
-}
-
-/*
- * Write the <xdr:blipFill> element.
- */
-STATIC void
-_drawing_write_blip_fill(lxw_drawing *self, uint16_t index)
-{
-    lxw_xml_start_tag(self->file, "xdr:blipFill", NULL);
-
-    /* Write the a:blip element. */
-    _drawing_write_a_blip(self, index);
-
-    /* Write the a:stretch element. */
-    _drawing_write_a_stretch(self);
-
-    lxw_xml_end_tag(self->file, "xdr:blipFill");
-}
-
-/*
- * Write the <a:ext> element.
- */
-STATIC void
-_drawing_write_a_ext(lxw_drawing *self, lxw_drawing_object *drawing_object)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("cx", drawing_object->width);
-    LXW_PUSH_ATTRIBUTES_INT("cy", drawing_object->height);
-
-    lxw_xml_empty_tag(self->file, "a:ext", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:off> element.
- */
-STATIC void
-_drawing_write_a_off(lxw_drawing *self, lxw_drawing_object *drawing_object)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("x", drawing_object->col_absolute);
-    LXW_PUSH_ATTRIBUTES_INT("y", drawing_object->row_absolute);
-
-    lxw_xml_empty_tag(self->file, "a:off", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:xfrm> element.
- */
-STATIC void
-_drawing_write_a_xfrm(lxw_drawing *self, lxw_drawing_object *drawing_object)
-{
-    lxw_xml_start_tag(self->file, "a:xfrm", NULL);
-
-    /* Write the a:off element. */
-    _drawing_write_a_off(self, drawing_object);
-
-    /* Write the a:ext element. */
-    _drawing_write_a_ext(self, drawing_object);
-
-    lxw_xml_end_tag(self->file, "a:xfrm");
-}
-
-/*
- * Write the <a:avLst> element.
- */
-STATIC void
-_drawing_write_a_av_lst(lxw_drawing *self)
-{
-    lxw_xml_empty_tag(self->file, "a:avLst", NULL);
-}
-
-/*
- * Write the <a:prstGeom> element.
- */
-STATIC void
-_drawing_write_a_prst_geom(lxw_drawing *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("prst", "rect");
-
-    lxw_xml_start_tag(self->file, "a:prstGeom", &attributes);
-
-    /* Write the a:avLst element. */
-    _drawing_write_a_av_lst(self);
-
-    lxw_xml_end_tag(self->file, "a:prstGeom");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xdr:spPr> element.
- */
-STATIC void
-_drawing_write_sp_pr(lxw_drawing *self, lxw_drawing_object *drawing_object)
-{
-    lxw_xml_start_tag(self->file, "xdr:spPr", NULL);
-
-    /* Write the a:xfrm element. */
-    _drawing_write_a_xfrm(self, drawing_object);
-
-    /* Write the a:prstGeom element. */
-    _drawing_write_a_prst_geom(self);
-
-    lxw_xml_end_tag(self->file, "xdr:spPr");
-}
-
-/*
- * Write the <xdr:pic> element.
- */
-STATIC void
-_drawing_write_pic(lxw_drawing *self, uint16_t index,
-                   lxw_drawing_object *drawing_object)
-{
-    lxw_xml_start_tag(self->file, "xdr:pic", NULL);
-
-    /* Write the xdr:nvPicPr element. */
-    _drawing_write_nv_pic_pr(self, index, drawing_object);
-
-    /* Write the xdr:blipFill element. */
-    _drawing_write_blip_fill(self, index);
-
-    /* Write the xdr:spPr element. */
-    _drawing_write_sp_pr(self, drawing_object);
-
-    lxw_xml_end_tag(self->file, "xdr:pic");
-}
-
-/*
- * Write the <xdr:clientData> element.
- */
-STATIC void
-_drawing_write_client_data(lxw_drawing *self)
-{
-    lxw_xml_empty_tag(self->file, "xdr:clientData", NULL);
-}
-
-/*
- * Write the <xdr:cNvGraphicFramePr> element.
- */
-STATIC void
-_drawing_write_c_nv_graphic_frame_pr(lxw_drawing *self)
-{
-    lxw_xml_empty_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
-}
-
-/*
- * Write the <xdr:nvGraphicFramePr> element.
- */
-STATIC void
-_drawing_write_nv_graphic_frame_pr(lxw_drawing *self, uint16_t index)
-{
-    lxw_xml_start_tag(self->file, "xdr:nvGraphicFramePr", NULL);
-
-    /* Write the xdr:cNvPr element. */
-    _drawing_write_c_nv_pr(self, "Chart", index, NULL);
-
-    /* Write the xdr:cNvGraphicFramePr element. */
-    _drawing_write_c_nv_graphic_frame_pr(self);
-
-    lxw_xml_end_tag(self->file, "xdr:nvGraphicFramePr");
-}
-
-/*
- * Write the <a:off> element.
- */
-STATIC void
-_drawing_write_xfrm_offset(lxw_drawing *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("x", "0");
-    LXW_PUSH_ATTRIBUTES_STR("y", "0");
-
-    lxw_xml_empty_tag(self->file, "a:off", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:ext> element.
- */
-STATIC void
-_drawing_write_xfrm_extension(lxw_drawing *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("cx", "0");
-    LXW_PUSH_ATTRIBUTES_STR("cy", "0");
-
-    lxw_xml_empty_tag(self->file, "a:ext", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xdr:xfrm> element.
- */
-STATIC void
-_drawing_write_xfrm(lxw_drawing *self)
-{
-    lxw_xml_start_tag(self->file, "xdr:xfrm", NULL);
-
-    /* Write the a:off element. */
-    _drawing_write_xfrm_offset(self);
-
-    /* Write the a:ext element. */
-    _drawing_write_xfrm_extension(self);
-
-    lxw_xml_end_tag(self->file, "xdr:xfrm");
-}
-
-/*
- * Write the <c:chart> element.
- */
-STATIC void
-_drawing_write_chart(lxw_drawing *self, uint16_t index)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns_c[] = LXW_SCHEMA_DRAWING "/chart";
-    char xmlns_r[] = LXW_SCHEMA_OFFICEDOC "/relationships";
-    char r_id[LXW_MAX_ATTRIBUTE_LENGTH];
-
-    lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", index);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:c", xmlns_c);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
-    LXW_PUSH_ATTRIBUTES_STR("r:id", r_id);
-
-    lxw_xml_empty_tag(self->file, "c:chart", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:graphicData> element.
- */
-STATIC void
-_drawing_write_a_graphic_data(lxw_drawing *self, uint16_t index)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char uri[] = LXW_SCHEMA_DRAWING "/chart";
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("uri", uri);
-
-    lxw_xml_start_tag(self->file, "a:graphicData", &attributes);
-
-    /* Write the c:chart element. */
-    _drawing_write_chart(self, index);
-
-    lxw_xml_end_tag(self->file, "a:graphicData");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <a:graphic> element.
- */
-STATIC void
-_drawing_write_a_graphic(lxw_drawing *self, uint16_t index)
-{
-
-    lxw_xml_start_tag(self->file, "a:graphic", NULL);
-
-    /* Write the a:graphicData element. */
-    _drawing_write_a_graphic_data(self, index);
-
-    lxw_xml_end_tag(self->file, "a:graphic");
-}
-
-/*
- * Write the <xdr:graphicFrame> element.
- */
-STATIC void
-_drawing_write_graphic_frame(lxw_drawing *self, uint16_t index)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("macro", "");
-
-    lxw_xml_start_tag(self->file, "xdr:graphicFrame", &attributes);
-
-    /* Write the xdr:nvGraphicFramePr element. */
-    _drawing_write_nv_graphic_frame_pr(self, index);
-
-    /* Write the xdr:xfrm element. */
-    _drawing_write_xfrm(self);
-
-    /* Write the a:graphic element. */
-    _drawing_write_a_graphic(self, index);
-
-    lxw_xml_end_tag(self->file, "xdr:graphicFrame");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xdr:twoCellAnchor> element.
- */
-STATIC void
-_drawing_write_two_cell_anchor(lxw_drawing *self, uint16_t index,
-                               lxw_drawing_object *drawing_object)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (drawing_object->anchor_type == LXW_ANCHOR_TYPE_IMAGE) {
-
-        if (drawing_object->edit_as == LXW_ANCHOR_EDIT_AS_ABSOLUTE)
-            LXW_PUSH_ATTRIBUTES_STR("editAs", "absolute");
-        else if (drawing_object->edit_as != LXW_ANCHOR_EDIT_AS_RELATIVE)
-            LXW_PUSH_ATTRIBUTES_STR("editAs", "oneCell");
-    }
-
-    lxw_xml_start_tag(self->file, "xdr:twoCellAnchor", &attributes);
-
-    _drawing_write_from(self, &drawing_object->from);
-    _drawing_write_to(self, &drawing_object->to);
-
-    if (drawing_object->anchor_type == LXW_ANCHOR_TYPE_CHART) {
-        /* Write the xdr:graphicFrame element for charts. */
-        _drawing_write_graphic_frame(self, index);
-    }
-    else if (drawing_object->anchor_type == LXW_ANCHOR_TYPE_IMAGE) {
-        /* Write the xdr:pic element. */
-        _drawing_write_pic(self, index, drawing_object);
-    }
-    else {
-        /* Write the xdr:sp element for shapes. */
-        /* _drawing_write_sp(self, index, col_absolute, row_absolute, width,
-           height,  shape); */
-    }
-
-    /* Write the xdr:clientData element. */
-    _drawing_write_client_data(self);
-
-    lxw_xml_end_tag(self->file, "xdr:twoCellAnchor");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_drawing_assemble_xml_file(lxw_drawing *self)
-{
-    uint16_t index;
-    lxw_drawing_object *drawing_object;
-
-    /* Write the XML declaration. */
-    _drawing_xml_declaration(self);
-
-    /* Write the xdr:wsDr element. */
-    _write_drawing_workspace(self);
-
-    if (self->embedded) {
-        index = 1;
-
-        STAILQ_FOREACH(drawing_object, self->drawing_objects, list_pointers) {
-            _drawing_write_two_cell_anchor(self, index, drawing_object);
-            index++;
-        }
-
-    }
-
-    lxw_xml_end_tag(self->file, "xdr:wsDr");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/

+ 0 - 223
library/src/hash_table.c

@@ -1,223 +0,0 @@
-/*****************************************************************************
- * hash_table - Hash table functions for libxlsxwriter.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include "xlsxwriter/hash_table.h"
-
-/*
- * Calculate the hash key using the FNV function. See:
- * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
- */
-STATIC size_t
-_generate_hash_key(void *data, size_t data_len, size_t num_buckets)
-{
-    unsigned char *p = data;
-    size_t hash = 2166136261U;
-    size_t i;
-
-    for (i = 0; i < data_len; i++)
-        hash = (hash * 16777619) ^ p[i];
-
-    return hash % num_buckets;
-}
-
-/*
- * Check if an element exists in the hash table and return a pointer
- * to it if it does.
- */
-lxw_hash_element *
-lxw_hash_key_exists(lxw_hash_table *lxw_hash, void *key, size_t key_len)
-{
-    size_t hash_key = _generate_hash_key(key, key_len, lxw_hash->num_buckets);
-    struct lxw_hash_bucket_list *list;
-    lxw_hash_element *element;
-
-    if (!lxw_hash->buckets[hash_key]) {
-        /* The key isn't in the LXW_HASH hash table. */
-        return NULL;
-    }
-    else {
-        /* The key is already in the table or there is a hash collision. */
-        list = lxw_hash->buckets[hash_key];
-
-        /* Iterate over the keys in the bucket's linked list. */
-        SLIST_FOREACH(element, list, lxw_hash_list_pointers) {
-            if (memcmp(element->key, key, key_len) == 0) {
-                /* The key already exists in the table. */
-                return element;
-            }
-        }
-
-        /* Key doesn't exist in the list so this is a hash collision. */
-        return NULL;
-    }
-}
-
-/*
- * Insert or update a value in the LXW_HASH table based on a key
- * and return a pointer to the new or updated element.
- */
-lxw_hash_element *
-lxw_insert_hash_element(lxw_hash_table *lxw_hash, void *key, void *value,
-                        size_t key_len)
-{
-    size_t hash_key = _generate_hash_key(key, key_len, lxw_hash->num_buckets);
-    struct lxw_hash_bucket_list *list = NULL;
-    lxw_hash_element *element = NULL;
-
-    if (!lxw_hash->buckets[hash_key]) {
-        /* The key isn't in the LXW_HASH hash table. */
-
-        /* Create a linked list in the bucket to hold the lxw_hash keys. */
-        list = calloc(1, sizeof(struct lxw_hash_bucket_list));
-        GOTO_LABEL_ON_MEM_ERROR(list, mem_error1);
-
-        /* Initialize the bucket linked list. */
-        SLIST_INIT(list);
-
-        /* Create an lxw_hash element to add to the linked list. */
-        element = calloc(1, sizeof(lxw_hash_element));
-        GOTO_LABEL_ON_MEM_ERROR(element, mem_error1);
-
-        /* Store the key and value. */
-        element->key = key;
-        element->value = value;
-
-        /* Add the lxw_hash element to the bucket's linked list. */
-        SLIST_INSERT_HEAD(list, element, lxw_hash_list_pointers);
-
-        /* Also add it to the insertion order linked list. */
-        STAILQ_INSERT_TAIL(lxw_hash->order_list, element,
-                           lxw_hash_order_pointers);
-
-        /* Store the bucket list at the hash index. */
-        lxw_hash->buckets[hash_key] = list;
-
-        lxw_hash->used_buckets++;
-        lxw_hash->unique_count++;
-
-        return element;
-    }
-    else {
-        /* The key is already in the table or there is a hash collision. */
-        list = lxw_hash->buckets[hash_key];
-
-        /* Iterate over the keys in the bucket's linked list. */
-        SLIST_FOREACH(element, list, lxw_hash_list_pointers) {
-            if (memcmp(element->key, key, key_len) == 0) {
-                /* The key already exists in the table. Update the value. */
-                if (lxw_hash->free_value)
-                    free(element->value);
-
-                element->value = value;
-                return element;
-            }
-        }
-
-        /* Key doesn't exist in the list so this is a hash collision.
-         * Create an lxw_hash element to add to the linked list. */
-        element = calloc(1, sizeof(lxw_hash_element));
-        GOTO_LABEL_ON_MEM_ERROR(element, mem_error2);
-
-        /* Store the key and value. */
-        element->key = key;
-        element->value = value;
-
-        /* Add the lxw_hash element to the bucket linked list. */
-        SLIST_INSERT_HEAD(list, element, lxw_hash_list_pointers);
-
-        /* Also add it to the insertion order linked list. */
-        STAILQ_INSERT_TAIL(lxw_hash->order_list, element,
-                           lxw_hash_order_pointers);
-
-        lxw_hash->unique_count++;
-
-        return element;
-    }
-
-mem_error1:
-    free(list);
-
-mem_error2:
-    free(element);
-    return NULL;
-}
-
-/*
- * Create a new LXW_HASH hash table object.
- */
-lxw_hash_table *
-lxw_hash_new(uint32_t num_buckets, uint8_t free_key, uint8_t free_value)
-{
-    /* Create the new hash table. */
-    lxw_hash_table *lxw_hash = calloc(1, sizeof(lxw_hash_table));
-    RETURN_ON_MEM_ERROR(lxw_hash, NULL);
-
-    lxw_hash->free_key = free_key;
-    lxw_hash->free_value = free_value;
-
-    /* Add the lxw_hash element buckets. */
-    lxw_hash->buckets =
-        calloc(num_buckets, sizeof(struct lxw_hash_bucket_list *));
-    GOTO_LABEL_ON_MEM_ERROR(lxw_hash->buckets, mem_error);
-
-    /* Add a list for tracking the insertion order. */
-    lxw_hash->order_list = calloc(1, sizeof(struct lxw_hash_order_list));
-    GOTO_LABEL_ON_MEM_ERROR(lxw_hash->order_list, mem_error);
-
-    /* Initialize the order list. */
-    STAILQ_INIT(lxw_hash->order_list);
-
-    /* Store the number of buckets to calculate the load factor. */
-    lxw_hash->num_buckets = num_buckets;
-
-    return lxw_hash;
-
-mem_error:
-    lxw_hash_free(lxw_hash);
-    return NULL;
-}
-
-/*
- * Free the LXW_HASH hash table object.
- */
-void
-lxw_hash_free(lxw_hash_table *lxw_hash)
-{
-    size_t i;
-    lxw_hash_element *element;
-    lxw_hash_element *element_temp;
-
-    if (!lxw_hash)
-        return;
-
-    /* Free the lxw_hash_elements and data using the ordered linked list. */
-    if (lxw_hash->order_list) {
-        STAILQ_FOREACH_SAFE(element, lxw_hash->order_list,
-                            lxw_hash_order_pointers, element_temp) {
-            if (lxw_hash->free_key)
-                free(element->key);
-            if (lxw_hash->free_value)
-                free(element->value);
-            free(element);
-        }
-    }
-
-    /* Free the buckets from the hash table. */
-    for (i = 0; i < lxw_hash->num_buckets; i++) {
-        free(lxw_hash->buckets[i]);
-    }
-
-    free(lxw_hash->order_list);
-    free(lxw_hash->buckets);
-    free(lxw_hash);
-}

+ 0 - 961
library/src/packager.c

@@ -1,961 +0,0 @@
-/*****************************************************************************
- * packager - A library for creating Excel XLSX packager files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/packager.h"
-#include "xlsxwriter/hash_table.h"
-#include "xlsxwriter/utility.h"
-
-STATIC lxw_error _add_file_to_zip(lxw_packager *self, FILE * file,
-                                  const char *filename);
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-/* Avoid non MSVC definition of _WIN32 in MinGW. */
-
-#ifdef __MINGW32__
-#undef _WIN32
-#endif
-
-#ifdef _WIN32
-
-/* Silence Windows warning with duplicate symbol for SLIST_ENTRY in local
- * queue.h and widows.h. */
-#undef SLIST_ENTRY
-
-#include <windows.h>
-
-#ifdef USE_SYSTEM_MINIZIP
-#include "minizip/iowin32.h"
-#else
-#include "../third_party/minizip/iowin32.h"
-#endif
-
-zipFile
-_open_zipfile_win32(const char *filename)
-{
-    int n;
-    zlib_filefunc64_def filefunc;
-
-    wchar_t wide_filename[_MAX_PATH + 1] = L"";
-
-    /* Build a UTF-16 filename for Win32. */
-    n = MultiByteToWideChar(CP_UTF8, 0, filename, (int) strlen(filename),
-                            wide_filename, _MAX_PATH);
-
-    if (n == 0) {
-        LXW_ERROR("MultiByteToWideChar error");
-        return NULL;
-    }
-
-    /* Use the native Win32 file handling functions with minizip. */
-    fill_win32_filefunc64W(&filefunc);
-
-    return zipOpen2_64(wide_filename, 0, NULL, &filefunc);
-}
-
-#endif
-
-/*
- * Create a new packager object.
- */
-lxw_packager *
-lxw_packager_new(const char *filename, char *tmpdir)
-{
-    lxw_packager *packager = calloc(1, sizeof(lxw_packager));
-    GOTO_LABEL_ON_MEM_ERROR(packager, mem_error);
-
-    packager->buffer = calloc(1, LXW_ZIP_BUFFER_SIZE);
-    GOTO_LABEL_ON_MEM_ERROR(packager->buffer, mem_error);
-
-    packager->filename = lxw_strdup(filename);
-    packager->tmpdir = tmpdir;
-    GOTO_LABEL_ON_MEM_ERROR(packager->filename, mem_error);
-
-    packager->buffer_size = LXW_ZIP_BUFFER_SIZE;
-
-    /* Initialize the zip_fileinfo struct to Jan 1 1980 like Excel. */
-    packager->zipfile_info.tmz_date.tm_sec = 0;
-    packager->zipfile_info.tmz_date.tm_min = 0;
-    packager->zipfile_info.tmz_date.tm_hour = 0;
-    packager->zipfile_info.tmz_date.tm_mday = 1;
-    packager->zipfile_info.tmz_date.tm_mon = 0;
-    packager->zipfile_info.tmz_date.tm_year = 1980;
-    packager->zipfile_info.dosDate = 0;
-    packager->zipfile_info.internal_fa = 0;
-    packager->zipfile_info.external_fa = 0;
-
-    /* Create a zip container for the xlsx file. */
-#ifdef _WIN32
-    packager->zipfile = _open_zipfile_win32(packager->filename);
-#else
-    packager->zipfile = zipOpen(packager->filename, 0);
-#endif
-
-    if (packager->zipfile == NULL)
-        goto mem_error;
-
-    return packager;
-
-mem_error:
-    lxw_packager_free(packager);
-    return NULL;
-}
-
-/*
- * Free a packager object.
- */
-void
-lxw_packager_free(lxw_packager *packager)
-{
-    if (!packager)
-        return;
-
-    free(packager->buffer);
-    free(packager->filename);
-    free(packager);
-}
-
-/*****************************************************************************
- *
- * File assembly functions.
- *
- ****************************************************************************/
-/*
- * Write the workbook.xml file.
- */
-STATIC lxw_error
-_write_workbook_file(lxw_packager *self)
-{
-    lxw_workbook *workbook = self->workbook;
-    lxw_error err;
-
-    workbook->file = lxw_tmpfile(self->tmpdir);
-    if (!workbook->file)
-        return LXW_ERROR_CREATING_TMPFILE;
-
-    lxw_workbook_assemble_xml_file(workbook);
-
-    err = _add_file_to_zip(self, workbook->file, "xl/workbook.xml");
-    RETURN_ON_ERROR(err);
-
-    fclose(workbook->file);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the worksheet files.
- */
-STATIC lxw_error
-_write_worksheet_files(lxw_packager *self)
-{
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    char sheetname[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 1;
-    lxw_error err;
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-        lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
-                     "xl/worksheets/sheet%d.xml", index++);
-
-        if (worksheet->optimize_row)
-            lxw_worksheet_write_single_row(worksheet);
-
-        worksheet->file = lxw_tmpfile(self->tmpdir);
-        if (!worksheet->file)
-            return LXW_ERROR_CREATING_TMPFILE;
-
-        lxw_worksheet_assemble_xml_file(worksheet);
-
-        err = _add_file_to_zip(self, worksheet->file, sheetname);
-        RETURN_ON_ERROR(err);
-
-        fclose(worksheet->file);
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the /xl/media/image?.xml files.
- */
-STATIC lxw_error
-_write_image_files(lxw_packager *self)
-{
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    lxw_image_options *image;
-    lxw_error err;
-    FILE *image_stream;
-
-    char filename[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 1;
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-
-        if (STAILQ_EMPTY(worksheet->image_data))
-            continue;
-
-        STAILQ_FOREACH(image, worksheet->image_data, list_pointers) {
-
-            lxw_snprintf(filename, LXW_FILENAME_LENGTH,
-                         "xl/media/image%d.%s", index++, image->extension);
-
-            /* Check that the image file exists and can be opened. */
-            image_stream = fopen(image->filename, "rb");
-            if (!image_stream) {
-                LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
-                                 "doesn't exist or can't be opened: %s.",
-                                 image->filename);
-                return LXW_ERROR_CREATING_TMPFILE;
-            }
-
-            err = _add_file_to_zip(self, image_stream, filename);
-            fclose(image_stream);
-
-            RETURN_ON_ERROR(err);
-        }
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the chart files.
- */
-STATIC lxw_error
-_write_chart_files(lxw_packager *self)
-{
-    lxw_workbook *workbook = self->workbook;
-    lxw_chart *chart;
-    char sheetname[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 1;
-    lxw_error err;
-
-    STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
-
-        lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
-                     "xl/charts/chart%d.xml", index++);
-
-        chart->file = lxw_tmpfile(self->tmpdir);
-        if (!chart->file)
-            return LXW_ERROR_CREATING_TMPFILE;
-
-        lxw_chart_assemble_xml_file(chart);
-
-        err = _add_file_to_zip(self, chart->file, sheetname);
-        RETURN_ON_ERROR(err);
-
-        self->chart_count++;
-
-        fclose(chart->file);
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the drawing files.
- */
-STATIC lxw_error
-_write_drawing_files(lxw_packager *self)
-{
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    lxw_drawing *drawing;
-    char filename[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 1;
-    lxw_error err;
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-        drawing = worksheet->drawing;
-
-        if (drawing) {
-            lxw_snprintf(filename, LXW_FILENAME_LENGTH,
-                         "xl/drawings/drawing%d.xml", index++);
-
-            drawing->file = lxw_tmpfile(self->tmpdir);
-            if (!drawing->file)
-                return LXW_ERROR_CREATING_TMPFILE;
-
-            lxw_drawing_assemble_xml_file(drawing);
-            err = _add_file_to_zip(self, drawing->file, filename);
-            RETURN_ON_ERROR(err);
-
-            fclose(drawing->file);
-
-            self->drawing_count++;
-        }
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the sharedStrings.xml file.
- */
-STATIC lxw_error
-_write_shared_strings_file(lxw_packager *self)
-{
-    lxw_sst *sst = self->workbook->sst;
-    lxw_error err;
-
-    /* Skip the sharedStrings file if there are no shared strings. */
-    if (!sst->string_count)
-        return LXW_NO_ERROR;
-
-    sst->file = lxw_tmpfile(self->tmpdir);
-    if (!sst->file)
-        return LXW_ERROR_CREATING_TMPFILE;
-
-    lxw_sst_assemble_xml_file(sst);
-
-    err = _add_file_to_zip(self, sst->file, "xl/sharedStrings.xml");
-    RETURN_ON_ERROR(err);
-
-    fclose(sst->file);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the app.xml file.
- */
-STATIC lxw_error
-_write_app_file(lxw_packager *self)
-{
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    lxw_defined_name *defined_name;
-    lxw_app *app;
-    uint16_t named_range_count = 0;
-    char *autofilter;
-    char *has_range;
-    char number[LXW_ATTR_32] = { 0 };
-    lxw_error err = LXW_NO_ERROR;
-
-    app = lxw_app_new();
-    if (!app) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    app->file = lxw_tmpfile(self->tmpdir);
-    if (!app->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    lxw_snprintf(number, LXW_ATTR_32, "%d", self->workbook->num_sheets);
-
-    lxw_app_add_heading_pair(app, "Worksheets", number);
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-        lxw_app_add_part_name(app, worksheet->name);
-    }
-
-    /* Add the Named Ranges parts. */
-    TAILQ_FOREACH(defined_name, workbook->defined_names, list_pointers) {
-
-        has_range = strchr(defined_name->formula, '!');
-        autofilter = strstr(defined_name->app_name, "_FilterDatabase");
-
-        /* Only store defined names with ranges (except for autofilters). */
-        if (has_range && !autofilter) {
-            lxw_app_add_part_name(app, defined_name->app_name);
-            named_range_count++;
-        }
-    }
-
-    /* Add the Named Range heading pairs. */
-    if (named_range_count) {
-        lxw_snprintf(number, LXW_ATTR_32, "%d", named_range_count);
-        lxw_app_add_heading_pair(app, "Named Ranges", number);
-    }
-
-    /* Set the app/doc properties. */
-    app->properties = workbook->properties;
-
-    lxw_app_assemble_xml_file(app);
-
-    err = _add_file_to_zip(self, app->file, "docProps/app.xml");
-
-    fclose(app->file);
-
-mem_error:
-    lxw_app_free(app);
-
-    return err;
-}
-
-/*
- * Write the core.xml file.
- */
-STATIC lxw_error
-_write_core_file(lxw_packager *self)
-{
-    lxw_error err = LXW_NO_ERROR;
-    lxw_core *core = lxw_core_new();
-
-    if (!core) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    core->file = lxw_tmpfile(self->tmpdir);
-    if (!core->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    core->properties = self->workbook->properties;
-
-    lxw_core_assemble_xml_file(core);
-
-    err = _add_file_to_zip(self, core->file, "docProps/core.xml");
-
-    fclose(core->file);
-
-mem_error:
-    lxw_core_free(core);
-
-    return err;
-}
-
-/*
- * Write the custom.xml file.
- */
-STATIC lxw_error
-_write_custom_file(lxw_packager *self)
-{
-    lxw_custom *custom;
-    lxw_error err = LXW_NO_ERROR;
-
-    if (STAILQ_EMPTY(self->workbook->custom_properties))
-        return LXW_NO_ERROR;
-
-    custom = lxw_custom_new();
-    if (!custom) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    custom->file = lxw_tmpfile(self->tmpdir);
-    if (!custom->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    custom->custom_properties = self->workbook->custom_properties;
-
-    lxw_custom_assemble_xml_file(custom);
-
-    err = _add_file_to_zip(self, custom->file, "docProps/custom.xml");
-
-    fclose(custom->file);
-
-mem_error:
-    lxw_custom_free(custom);
-    return err;
-}
-
-/*
- * Write the theme.xml file.
- */
-STATIC lxw_error
-_write_theme_file(lxw_packager *self)
-{
-    lxw_error err = LXW_NO_ERROR;
-    lxw_theme *theme = lxw_theme_new();
-
-    if (!theme) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    theme->file = lxw_tmpfile(self->tmpdir);
-    if (!theme->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    lxw_theme_assemble_xml_file(theme);
-
-    err = _add_file_to_zip(self, theme->file, "xl/theme/theme1.xml");
-
-    fclose(theme->file);
-
-mem_error:
-    lxw_theme_free(theme);
-
-    return err;
-}
-
-/*
- * Write the styles.xml file.
- */
-STATIC lxw_error
-_write_styles_file(lxw_packager *self)
-{
-    lxw_styles *styles = lxw_styles_new();
-    lxw_hash_element *hash_element;
-    lxw_error err = LXW_NO_ERROR;
-
-    if (!styles) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    /* Copy the unique and in-use formats from the workbook to the styles
-     * xf_format list. */
-    LXW_FOREACH_ORDERED(hash_element, self->workbook->used_xf_formats) {
-        lxw_format *workbook_format = (lxw_format *) hash_element->value;
-        lxw_format *style_format = lxw_format_new();
-
-        if (!style_format) {
-            err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-            goto mem_error;
-        }
-
-        memcpy(style_format, workbook_format, sizeof(lxw_format));
-        STAILQ_INSERT_TAIL(styles->xf_formats, style_format, list_pointers);
-    }
-
-    styles->font_count = self->workbook->font_count;
-    styles->border_count = self->workbook->border_count;
-    styles->fill_count = self->workbook->fill_count;
-    styles->num_format_count = self->workbook->num_format_count;
-    styles->xf_count = self->workbook->used_xf_formats->unique_count;
-
-    styles->file = lxw_tmpfile(self->tmpdir);
-    if (!styles->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    lxw_styles_assemble_xml_file(styles);
-
-    err = _add_file_to_zip(self, styles->file, "xl/styles.xml");
-
-    fclose(styles->file);
-
-mem_error:
-    lxw_styles_free(styles);
-
-    return err;
-}
-
-/*
- * Write the ContentTypes.xml file.
- */
-STATIC lxw_error
-_write_content_types_file(lxw_packager *self)
-{
-    lxw_content_types *content_types = lxw_content_types_new();
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
-    uint16_t index = 1;
-    lxw_error err = LXW_NO_ERROR;
-
-    if (!content_types) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    content_types->file = lxw_tmpfile(self->tmpdir);
-    if (!content_types->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    if (workbook->has_png)
-        lxw_ct_add_default(content_types, "png", "image/png");
-
-    if (workbook->has_jpeg)
-        lxw_ct_add_default(content_types, "jpeg", "image/jpeg");
-
-    if (workbook->has_bmp)
-        lxw_ct_add_default(content_types, "bmp", "image/bmp");
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
-                     "/xl/worksheets/sheet%d.xml", index++);
-        lxw_ct_add_worksheet_name(content_types, filename);
-    }
-
-    for (index = 1; index <= self->chart_count; index++) {
-        lxw_snprintf(filename, LXW_FILENAME_LENGTH, "/xl/charts/chart%d.xml",
-                     index);
-        lxw_ct_add_chart_name(content_types, filename);
-    }
-
-    for (index = 1; index <= self->drawing_count; index++) {
-        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
-                     "/xl/drawings/drawing%d.xml", index);
-        lxw_ct_add_drawing_name(content_types, filename);
-    }
-
-    if (workbook->sst->string_count)
-        lxw_ct_add_shared_strings(content_types);
-
-    if (!STAILQ_EMPTY(self->workbook->custom_properties))
-        lxw_ct_add_custom_properties(content_types);
-
-    lxw_content_types_assemble_xml_file(content_types);
-
-    err = _add_file_to_zip(self, content_types->file, "[Content_Types].xml");
-
-    fclose(content_types->file);
-
-mem_error:
-    lxw_content_types_free(content_types);
-
-    return err;
-}
-
-/*
- * Write the workbook .rels xml file.
- */
-STATIC lxw_error
-_write_workbook_rels_file(lxw_packager *self)
-{
-    lxw_relationships *rels = lxw_relationships_new();
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    char sheetname[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 1;
-    lxw_error err = LXW_NO_ERROR;
-
-    if (!rels) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    rels->file = lxw_tmpfile(self->tmpdir);
-    if (!rels->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-        lxw_snprintf(sheetname, LXW_FILENAME_LENGTH, "worksheets/sheet%d.xml",
-                     index++);
-        lxw_add_document_relationship(rels, "/worksheet", sheetname);
-    }
-
-    lxw_add_document_relationship(rels, "/theme", "theme/theme1.xml");
-    lxw_add_document_relationship(rels, "/styles", "styles.xml");
-
-    if (workbook->sst->string_count)
-        lxw_add_document_relationship(rels, "/sharedStrings",
-                                      "sharedStrings.xml");
-
-    lxw_relationships_assemble_xml_file(rels);
-
-    err = _add_file_to_zip(self, rels->file, "xl/_rels/workbook.xml.rels");
-
-    fclose(rels->file);
-
-mem_error:
-    lxw_free_relationships(rels);
-
-    return err;
-}
-
-/*
- * Write the worksheet .rels files for worksheets that contain links to
- * external data such as hyperlinks or drawings.
- */
-STATIC lxw_error
-_write_worksheet_rels_file(lxw_packager *self)
-{
-    lxw_relationships *rels;
-    lxw_rel_tuple *rel;
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    char sheetname[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 0;
-    lxw_error err;
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-
-        index++;
-
-        if (STAILQ_EMPTY(worksheet->external_hyperlinks) &&
-            STAILQ_EMPTY(worksheet->external_drawing_links))
-            continue;
-
-        rels = lxw_relationships_new();
-
-        rels->file = lxw_tmpfile(self->tmpdir);
-        if (!rels->file) {
-            lxw_free_relationships(rels);
-            return LXW_ERROR_CREATING_TMPFILE;
-        }
-
-        STAILQ_FOREACH(rel, worksheet->external_hyperlinks, list_pointers) {
-            lxw_add_worksheet_relationship(rels, rel->type, rel->target,
-                                           rel->target_mode);
-        }
-
-        STAILQ_FOREACH(rel, worksheet->external_drawing_links, list_pointers) {
-            lxw_add_worksheet_relationship(rels, rel->type, rel->target,
-                                           rel->target_mode);
-        }
-
-        lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
-                     "xl/worksheets/_rels/sheet%d.xml.rels", index);
-
-        lxw_relationships_assemble_xml_file(rels);
-
-        err = _add_file_to_zip(self, rels->file, sheetname);
-
-        fclose(rels->file);
-        lxw_free_relationships(rels);
-
-        RETURN_ON_ERROR(err);
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the drawing .rels files for worksheets that contain charts or
- * drawings.
- */
-STATIC lxw_error
-_write_drawing_rels_file(lxw_packager *self)
-{
-    lxw_relationships *rels;
-    lxw_rel_tuple *rel;
-    lxw_workbook *workbook = self->workbook;
-    lxw_worksheet *worksheet;
-    char sheetname[LXW_FILENAME_LENGTH] = { 0 };
-    uint16_t index = 1;
-    lxw_error err;
-
-    STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
-
-        if (STAILQ_EMPTY(worksheet->drawing_links))
-            continue;
-
-        rels = lxw_relationships_new();
-
-        rels->file = lxw_tmpfile(self->tmpdir);
-        if (!rels->file) {
-            lxw_free_relationships(rels);
-            return LXW_ERROR_CREATING_TMPFILE;
-        }
-
-        STAILQ_FOREACH(rel, worksheet->drawing_links, list_pointers) {
-            lxw_add_worksheet_relationship(rels, rel->type, rel->target,
-                                           rel->target_mode);
-
-        }
-
-        lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
-                     "xl/drawings/_rels/drawing%d.xml.rels", index++);
-
-        lxw_relationships_assemble_xml_file(rels);
-
-        err = _add_file_to_zip(self, rels->file, sheetname);
-
-        fclose(rels->file);
-        lxw_free_relationships(rels);
-
-        RETURN_ON_ERROR(err);
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the _rels/.rels xml file.
- */
-STATIC lxw_error
-_write_root_rels_file(lxw_packager *self)
-{
-    lxw_relationships *rels = lxw_relationships_new();
-    lxw_error err = LXW_NO_ERROR;
-
-    if (!rels) {
-        err = LXW_ERROR_MEMORY_MALLOC_FAILED;
-        goto mem_error;
-    }
-
-    rels->file = lxw_tmpfile(self->tmpdir);
-    if (!rels->file) {
-        err = LXW_ERROR_CREATING_TMPFILE;
-        goto mem_error;
-    }
-
-    lxw_add_document_relationship(rels, "/officeDocument", "xl/workbook.xml");
-
-    lxw_add_package_relationship(rels,
-                                 "/metadata/core-properties",
-                                 "docProps/core.xml");
-
-    lxw_add_document_relationship(rels,
-                                  "/extended-properties", "docProps/app.xml");
-
-    if (!STAILQ_EMPTY(self->workbook->custom_properties))
-        lxw_add_document_relationship(rels,
-                                      "/custom-properties",
-                                      "docProps/custom.xml");
-
-    lxw_relationships_assemble_xml_file(rels);
-
-    err = _add_file_to_zip(self, rels->file, "_rels/.rels");
-
-    fclose(rels->file);
-
-mem_error:
-    lxw_free_relationships(rels);
-
-    return err;
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-STATIC lxw_error
-_add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
-{
-    int16_t error = ZIP_OK;
-    size_t size_read;
-
-    error = zipOpenNewFileInZip4_64(self->zipfile,
-                                    filename,
-                                    &self->zipfile_info,
-                                    NULL, 0, NULL, 0, NULL,
-                                    Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
-                                    -MAX_WBITS, DEF_MEM_LEVEL,
-                                    Z_DEFAULT_STRATEGY, NULL, 0, 0, 0, 0);
-
-    if (error != ZIP_OK) {
-        LXW_ERROR("Error adding member to zipfile");
-        RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
-    }
-
-    fflush(file);
-    rewind(file);
-
-    size_read = fread(self->buffer, 1, self->buffer_size, file);
-
-    while (size_read) {
-
-        if (size_read < self->buffer_size) {
-            if (feof(file) == 0) {
-                LXW_ERROR("Error reading member file data");
-                RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
-            }
-        }
-
-        error = zipWriteInFileInZip(self->zipfile,
-                                    self->buffer, (unsigned int) size_read);
-
-        if (error < 0) {
-            LXW_ERROR("Error in writing member in the zipfile");
-            RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
-        }
-
-        size_read = fread(self->buffer, 1, self->buffer_size, file);
-    }
-
-    if (error < 0) {
-        RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
-    }
-    else {
-        error = zipCloseFileInZip(self->zipfile);
-        if (error != ZIP_OK) {
-            LXW_ERROR("Error in closing member in the zipfile");
-            RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
-        }
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write the xml files that make up the XLXS OPC package.
- */
-lxw_error
-lxw_create_package(lxw_packager *self)
-{
-    lxw_error error;
-    int8_t zip_error;
-
-    error = _write_worksheet_files(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_workbook_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_chart_files(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_drawing_files(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_shared_strings_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_app_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_core_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_custom_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_theme_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_styles_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_content_types_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_workbook_rels_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_worksheet_rels_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_drawing_rels_file(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_image_files(self);
-    RETURN_ON_ERROR(error);
-
-    error = _write_root_rels_file(self);
-    RETURN_ON_ERROR(error);
-
-    zip_error = zipClose(self->zipfile, NULL);
-    if (zip_error) {
-        RETURN_ON_ZIP_ERROR(zip_error, LXW_ERROR_ZIP_CLOSE);
-    }
-
-    return LXW_NO_ERROR;
-}

+ 0 - 245
library/src/relationships.c

@@ -1,245 +0,0 @@
-/*****************************************************************************
- * relationships - A library for creating Excel XLSX relationships files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include <string.h>
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/relationships.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new relationships object.
- */
-lxw_relationships *
-lxw_relationships_new()
-{
-    lxw_relationships *rels = calloc(1, sizeof(lxw_relationships));
-    GOTO_LABEL_ON_MEM_ERROR(rels, mem_error);
-
-    rels->relationships = calloc(1, sizeof(struct lxw_rel_tuples));
-    GOTO_LABEL_ON_MEM_ERROR(rels->relationships, mem_error);
-    STAILQ_INIT(rels->relationships);
-
-    return rels;
-
-mem_error:
-    lxw_free_relationships(rels);
-    return NULL;
-}
-
-/*
- * Free a relationships object.
- */
-void
-lxw_free_relationships(lxw_relationships *rels)
-{
-    lxw_rel_tuple *relationship;
-
-    if (!rels)
-        return;
-
-    if (rels->relationships) {
-        while (!STAILQ_EMPTY(rels->relationships)) {
-            relationship = STAILQ_FIRST(rels->relationships);
-            STAILQ_REMOVE_HEAD(rels->relationships, list_pointers);
-            free(relationship->type);
-            free(relationship->target);
-            free(relationship->target_mode);
-            free(relationship);
-        }
-
-        free(rels->relationships);
-    }
-
-    free(rels);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_relationships_xml_declaration(lxw_relationships *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <Relationship> element.
- */
-STATIC void
-_write_relationship(lxw_relationships *self, const char *type,
-                    const char *target, const char *target_mode)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char r_id[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
-
-    self->rel_id++;
-    lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", self->rel_id);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("Id", r_id);
-    LXW_PUSH_ATTRIBUTES_STR("Type", type);
-    LXW_PUSH_ATTRIBUTES_STR("Target", target);
-
-    if (target_mode)
-        LXW_PUSH_ATTRIBUTES_STR("TargetMode", target_mode);
-
-    lxw_xml_empty_tag(self->file, "Relationship", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <Relationships> element.
- */
-STATIC void
-_write_relationships(lxw_relationships *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_rel_tuple *rel;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", LXW_SCHEMA_PACKAGE);
-
-    lxw_xml_start_tag(self->file, "Relationships", &attributes);
-
-    STAILQ_FOREACH(rel, self->relationships, list_pointers) {
-        _write_relationship(self, rel->type, rel->target, rel->target_mode);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_relationships_assemble_xml_file(lxw_relationships *self)
-{
-    /* Write the XML declaration. */
-    _relationships_xml_declaration(self);
-
-    _write_relationships(self);
-
-    /* Close the relationships tag. */
-    lxw_xml_end_tag(self->file, "Relationships");
-}
-
-/*
- * Add a generic container relationship to XLSX .rels xml files.
- */
-STATIC void
-_add_relationship(lxw_relationships *self, const char *schema,
-                  const char *type, const char *target,
-                  const char *target_mode)
-{
-    lxw_rel_tuple *relationship;
-
-    if (!schema || !type || !target)
-        return;
-
-    relationship = calloc(1, sizeof(lxw_rel_tuple));
-    GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
-
-    relationship->type = calloc(1, LXW_MAX_ATTRIBUTE_LENGTH);
-    GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
-
-    /* Add the schema to the relationship type. */
-    lxw_snprintf(relationship->type, LXW_MAX_ATTRIBUTE_LENGTH, "%s%s",
-                 schema, type);
-
-    relationship->target = lxw_strdup(target);
-    GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
-
-    if (target_mode) {
-        relationship->target_mode = lxw_strdup(target_mode);
-        GOTO_LABEL_ON_MEM_ERROR(relationship->target_mode, mem_error);
-    }
-
-    STAILQ_INSERT_TAIL(self->relationships, relationship, list_pointers);
-
-    return;
-
-mem_error:
-    if (relationship) {
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-/*
- * Add a document relationship to XLSX .rels xml files.
- */
-void
-lxw_add_document_relationship(lxw_relationships *self, const char *type,
-                              const char *target)
-{
-    _add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, NULL);
-}
-
-/*
- * Add a package relationship to XLSX .rels xml files.
- */
-void
-lxw_add_package_relationship(lxw_relationships *self, const char *type,
-                             const char *target)
-{
-    _add_relationship(self, LXW_SCHEMA_PACKAGE, type, target, NULL);
-}
-
-/*
- * Add a MS schema package relationship to XLSX .rels xml files.
- */
-void
-lxw_add_ms_package_relationship(lxw_relationships *self, const char *type,
-                                const char *target)
-{
-    _add_relationship(self, LXW_SCHEMA_MS, type, target, NULL);
-}
-
-/*
- * Add a worksheet relationship to sheet .rels xml files.
- */
-void
-lxw_add_worksheet_relationship(lxw_relationships *self, const char *type,
-                               const char *target, const char *target_mode)
-{
-    _add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, target_mode);
-}

+ 0 - 266
library/src/shared_strings.c

@@ -1,266 +0,0 @@
-/*****************************************************************************
- * shared_strings - A library for creating Excel XLSX sst files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/shared_strings.h"
-#include "xlsxwriter/utility.h"
-#include <ctype.h>
-
-/*
- * Forward declarations.
- */
-
-STATIC int _element_cmp(struct sst_element *element1,
-                        struct sst_element *element2);
-
-#ifndef __clang_analyzer__
-LXW_RB_GENERATE_ELEMENT(sst_rb_tree, sst_element, sst_tree_pointers,
-                        _element_cmp);
-#endif
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new SST SharedString object.
- */
-lxw_sst *
-lxw_sst_new()
-{
-    /* Create the new shared string table. */
-    lxw_sst *sst = calloc(1, sizeof(lxw_sst));
-    RETURN_ON_MEM_ERROR(sst, NULL);
-
-    /* Add the sst RB tree. */
-    sst->rb_tree = calloc(1, sizeof(struct sst_rb_tree));
-    GOTO_LABEL_ON_MEM_ERROR(sst->rb_tree, mem_error);
-
-    /* Add a list for tracking the insertion order. */
-    sst->order_list = calloc(1, sizeof(struct sst_order_list));
-    GOTO_LABEL_ON_MEM_ERROR(sst->order_list, mem_error);
-
-    /* Initialize the order list. */
-    STAILQ_INIT(sst->order_list);
-
-    /* Initialize the RB tree. */
-    RB_INIT(sst->rb_tree);
-
-    return sst;
-
-mem_error:
-    lxw_sst_free(sst);
-    return NULL;
-}
-
-/*
- * Free a SST SharedString table object.
- */
-void
-lxw_sst_free(lxw_sst *sst)
-{
-    struct sst_element *sst_element;
-    struct sst_element *sst_element_temp;
-
-    if (!sst)
-        return;
-
-    /* Free the sst_elements and their data using the ordered linked list. */
-    if (sst->order_list) {
-        STAILQ_FOREACH_SAFE(sst_element, sst->order_list, sst_order_pointers,
-                            sst_element_temp) {
-
-            if (sst_element && sst_element->string)
-                free(sst_element->string);
-            if (sst_element)
-                free(sst_element);
-        }
-    }
-
-    free(sst->order_list);
-    free(sst->rb_tree);
-    free(sst);
-}
-
-/*
- * Comparator for the element structure
- */
-STATIC int
-_element_cmp(struct sst_element *element1, struct sst_element *element2)
-{
-    return strcmp(element1->string, element2->string);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-/*
- * Write the XML declaration.
- */
-STATIC void
-_sst_xml_declaration(lxw_sst *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <t> element.
- */
-STATIC void
-_write_t(lxw_sst *self, char *string)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Add attribute to preserve leading or trailing whitespace. */
-    if (isspace((unsigned char) string[0])
-        || isspace((unsigned char) string[strlen(string) - 1]))
-        LXW_PUSH_ATTRIBUTES_STR("xml:space", "preserve");
-
-    lxw_xml_data_element(self->file, "t", string, &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <si> element.
- */
-STATIC void
-_write_si(lxw_sst *self, char *string)
-{
-    uint8_t escaped_string = LXW_FALSE;
-
-    lxw_xml_start_tag(self->file, "si", NULL);
-
-    /* Look for and escape control chars in the string. */
-    if (strpbrk(string, "\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C"
-                "\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"
-                "\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) {
-        string = lxw_escape_control_characters(string);
-        escaped_string = LXW_TRUE;
-    }
-
-    /* Write the t element. */
-    _write_t(self, string);
-
-    lxw_xml_end_tag(self->file, "si");
-
-    if (escaped_string)
-        free(string);
-}
-
-/*
- * Write the <sst> element.
- */
-STATIC void
-_write_sst(lxw_sst *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns[] =
-        "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
-    LXW_PUSH_ATTRIBUTES_INT("count", self->string_count);
-    LXW_PUSH_ATTRIBUTES_INT("uniqueCount", self->unique_count);
-
-    lxw_xml_start_tag(self->file, "sst", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-STATIC void
-_write_sst_strings(lxw_sst *self)
-{
-    struct sst_element *sst_element;
-
-    STAILQ_FOREACH(sst_element, self->order_list, sst_order_pointers) {
-        /* Write the si element. */
-        _write_si(self, sst_element->string);
-    }
-}
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_sst_assemble_xml_file(lxw_sst *self)
-{
-    /* Write the XML declaration. */
-    _sst_xml_declaration(self);
-
-    /* Write the sst element. */
-    _write_sst(self);
-
-    /* Write the sst strings. */
-    _write_sst_strings(self);
-
-    /* Close the sst tag. */
-    lxw_xml_end_tag(self->file, "sst");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-/*
- * Add to or find a string in the SST SharedString table and return it's index.
- */
-struct sst_element *
-lxw_get_sst_index(lxw_sst *sst, const char *string)
-{
-    struct sst_element *element;
-    struct sst_element *existing_element;
-
-    /* Create an sst element to potentially add to the table. */
-    element = calloc(1, sizeof(struct sst_element));
-    if (!element)
-        return NULL;
-
-    /* Create potential new element with the string and its index. */
-    element->index = sst->unique_count;
-    element->string = lxw_strdup(string);
-
-    /* Try to insert it and see whether we already have that string. */
-    existing_element = RB_INSERT(sst_rb_tree, sst->rb_tree, element);
-
-    /* If existing_element is not NULL, then it already existed. */
-    /* Free new created element. */
-    if (existing_element) {
-        free(element->string);
-        free(element);
-        sst->string_count++;
-        return existing_element;
-    }
-
-    /* If it didn't exist, also add it to the insertion order linked list. */
-    STAILQ_INSERT_TAIL(sst->order_list, element, sst_order_pointers);
-
-    /* Update SST string counts. */
-    sst->string_count++;
-    sst->unique_count++;
-    return element;
-}

+ 0 - 1088
library/src/styles.c

@@ -1,1088 +0,0 @@
-/*****************************************************************************
- * styles - A library for creating Excel XLSX styles files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/styles.h"
-#include "xlsxwriter/utility.h"
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new styles object.
- */
-lxw_styles *
-lxw_styles_new()
-{
-    lxw_styles *styles = calloc(1, sizeof(lxw_styles));
-    GOTO_LABEL_ON_MEM_ERROR(styles, mem_error);
-
-    styles->xf_formats = calloc(1, sizeof(struct lxw_formats));
-    GOTO_LABEL_ON_MEM_ERROR(styles->xf_formats, mem_error);
-
-    STAILQ_INIT(styles->xf_formats);
-
-    return styles;
-
-mem_error:
-    lxw_styles_free(styles);
-    return NULL;
-}
-
-/*
- * Free a styles object.
- */
-void
-lxw_styles_free(lxw_styles *styles)
-{
-    lxw_format *format;
-
-    if (!styles)
-        return;
-
-    /* Free the formats in the styles. */
-    if (styles->xf_formats) {
-        while (!STAILQ_EMPTY(styles->xf_formats)) {
-            format = STAILQ_FIRST(styles->xf_formats);
-            STAILQ_REMOVE_HEAD(styles->xf_formats, list_pointers);
-            free(format);
-        }
-        free(styles->xf_formats);
-    }
-
-    free(styles);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_styles_xml_declaration(lxw_styles *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <styleSheet> element.
- */
-STATIC void
-_write_style_sheet(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns",
-                            "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
-
-    lxw_xml_start_tag(self->file, "styleSheet", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <numFmt> element.
- */
-STATIC void
-_write_num_fmt(lxw_styles *self, uint16_t num_fmt_id, char *format_code)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("numFmtId", num_fmt_id);
-    LXW_PUSH_ATTRIBUTES_STR("formatCode", format_code);
-
-    lxw_xml_empty_tag(self->file, "numFmt", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <numFmts> element.
- */
-STATIC void
-_write_num_fmts(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_format *format;
-
-    if (!self->num_format_count)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", self->num_format_count);
-
-    lxw_xml_start_tag(self->file, "numFmts", &attributes);
-
-    /* Write the numFmts elements. */
-    STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
-
-        /* Ignore built-in number formats, i.e., < 164. */
-        if (format->num_format_index < 164)
-            continue;
-
-        _write_num_fmt(self, format->num_format_index, format->num_format);
-    }
-
-    lxw_xml_end_tag(self->file, "numFmts");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <sz> element.
- */
-STATIC void
-_write_font_size(lxw_styles *self, double font_size)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("val", font_size);
-
-    lxw_xml_empty_tag(self->file, "sz", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <color> element for themes.
- */
-STATIC void
-_write_font_color_theme(lxw_styles *self, uint8_t theme)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("theme", theme);
-
-    lxw_xml_empty_tag(self->file, "color", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <color> element for RGB colors.
- */
-STATIC void
-_write_font_color_rgb(lxw_styles *self, int32_t rgb)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char rgb_str[LXW_ATTR_32];
-
-    lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", rgb & LXW_COLOR_MASK);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
-
-    lxw_xml_empty_tag(self->file, "color", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <name> element.
- */
-STATIC void
-_write_font_name(lxw_styles *self, const char *font_name)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (*font_name)
-        LXW_PUSH_ATTRIBUTES_STR("val", font_name);
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", LXW_DEFAULT_FONT_NAME);
-
-    lxw_xml_empty_tag(self->file, "name", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <family> element.
- */
-STATIC void
-_write_font_family(lxw_styles *self, uint8_t font_family)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("val", font_family);
-
-    lxw_xml_empty_tag(self->file, "family", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <scheme> element.
- */
-STATIC void
-_write_font_scheme(lxw_styles *self, const char *font_scheme)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (*font_scheme)
-        LXW_PUSH_ATTRIBUTES_STR("val", font_scheme);
-    else
-        LXW_PUSH_ATTRIBUTES_STR("val", "minor");
-
-    lxw_xml_empty_tag(self->file, "scheme", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the underline font element.
- */
-STATIC void
-_write_font_underline(lxw_styles *self, uint8_t underline)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Handle the underline variants. */
-    if (underline == LXW_UNDERLINE_DOUBLE)
-        LXW_PUSH_ATTRIBUTES_STR("val", "double");
-    else if (underline == LXW_UNDERLINE_SINGLE_ACCOUNTING)
-        LXW_PUSH_ATTRIBUTES_STR("val", "singleAccounting");
-    else if (underline == LXW_UNDERLINE_DOUBLE_ACCOUNTING)
-        LXW_PUSH_ATTRIBUTES_STR("val", "doubleAccounting");
-    /* Default to single underline. */
-
-    lxw_xml_empty_tag(self->file, "u", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-
-}
-
-/*
- * Write the <vertAlign> font sub-element.
- */
-STATIC void
-_write_vert_align(lxw_styles *self, const char *align)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("val", align);
-
-    lxw_xml_empty_tag(self->file, "vertAlign", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <font> element.
- */
-STATIC void
-_write_font(lxw_styles *self, lxw_format *format)
-{
-    lxw_xml_start_tag(self->file, "font", NULL);
-
-    if (format->bold)
-        lxw_xml_empty_tag(self->file, "b", NULL);
-
-    if (format->italic)
-        lxw_xml_empty_tag(self->file, "i", NULL);
-
-    if (format->font_strikeout)
-        lxw_xml_empty_tag(self->file, "strike", NULL);
-
-    if (format->font_outline)
-        lxw_xml_empty_tag(self->file, "outline", NULL);
-
-    if (format->font_shadow)
-        lxw_xml_empty_tag(self->file, "shadow", NULL);
-
-    if (format->underline)
-        _write_font_underline(self, format->underline);
-
-    if (format->font_script == LXW_FONT_SUPERSCRIPT)
-        _write_vert_align(self, "superscript");
-
-    if (format->font_script == LXW_FONT_SUBSCRIPT)
-        _write_vert_align(self, "subscript");
-
-    if (format->font_size > 0.0)
-        _write_font_size(self, format->font_size);
-
-    if (format->theme)
-        _write_font_color_theme(self, format->theme);
-    else if (format->font_color != LXW_COLOR_UNSET)
-        _write_font_color_rgb(self, format->font_color);
-    else
-        _write_font_color_theme(self, LXW_DEFAULT_FONT_THEME);
-
-    _write_font_name(self, format->font_name);
-    _write_font_family(self, format->font_family);
-
-    /* Only write the scheme element for the default font type if it
-     * is a hyperlink. */
-    if ((!*format->font_name
-         || strcmp(LXW_DEFAULT_FONT_NAME, format->font_name) == 0)
-        && !format->hyperlink) {
-        _write_font_scheme(self, format->font_scheme);
-    }
-
-    lxw_xml_end_tag(self->file, "font");
-}
-
-/*
- * Write the <fonts> element.
- */
-STATIC void
-_write_fonts(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_format *format;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", self->font_count);
-
-    lxw_xml_start_tag(self->file, "fonts", &attributes);
-
-    STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
-        if (format->has_font)
-            _write_font(self, format);
-    }
-
-    lxw_xml_end_tag(self->file, "fonts");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the default <fill> element.
- */
-STATIC void
-_write_default_fill(lxw_styles *self, const char *pattern)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("patternType", pattern);
-
-    lxw_xml_start_tag(self->file, "fill", NULL);
-    lxw_xml_empty_tag(self->file, "patternFill", &attributes);
-    lxw_xml_end_tag(self->file, "fill");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <fgColor> element.
- */
-STATIC void
-_write_fg_color(lxw_styles *self, lxw_color_t color)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char rgb_str[LXW_ATTR_32];
-
-    LXW_INIT_ATTRIBUTES();
-
-    lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
-    LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
-
-    lxw_xml_empty_tag(self->file, "fgColor", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <bgColor> element.
- */
-STATIC void
-_write_bg_color(lxw_styles *self, lxw_color_t color)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char rgb_str[LXW_ATTR_32];
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (color == LXW_COLOR_UNSET) {
-        LXW_PUSH_ATTRIBUTES_STR("indexed", "64");
-    }
-    else {
-        lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
-        LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
-    }
-
-    lxw_xml_empty_tag(self->file, "bgColor", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <fill> element.
- */
-STATIC void
-_write_fill(lxw_styles *self, lxw_format *format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    uint8_t pattern = format->pattern;
-    lxw_color_t bg_color = format->bg_color;
-    lxw_color_t fg_color = format->fg_color;
-
-    char *patterns[] = {
-        "none",
-        "solid",
-        "mediumGray",
-        "darkGray",
-        "lightGray",
-        "darkHorizontal",
-        "darkVertical",
-        "darkDown",
-        "darkUp",
-        "darkGrid",
-        "darkTrellis",
-        "lightHorizontal",
-        "lightVertical",
-        "lightDown",
-        "lightUp",
-        "lightGrid",
-        "lightTrellis",
-        "gray125",
-        "gray0625",
-    };
-
-    LXW_INIT_ATTRIBUTES();
-
-    lxw_xml_start_tag(self->file, "fill", NULL);
-
-    if (pattern)
-        LXW_PUSH_ATTRIBUTES_STR("patternType", patterns[pattern]);
-
-    lxw_xml_start_tag(self->file, "patternFill", &attributes);
-
-    if (fg_color != LXW_COLOR_UNSET)
-        _write_fg_color(self, fg_color);
-
-    _write_bg_color(self, bg_color);
-
-    lxw_xml_end_tag(self->file, "patternFill");
-    lxw_xml_end_tag(self->file, "fill");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <fills> element.
- */
-STATIC void
-_write_fills(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_format *format;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", self->fill_count);
-
-    lxw_xml_start_tag(self->file, "fills", &attributes);
-
-    /* Write the default fills. */
-    _write_default_fill(self, "none");
-    _write_default_fill(self, "gray125");
-
-    STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
-        if (format->has_fill)
-            _write_fill(self, format);
-    }
-
-    lxw_xml_end_tag(self->file, "fills");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the border <color> element.
- */
-STATIC void
-_write_border_color(lxw_styles *self, lxw_color_t color)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char rgb_str[LXW_ATTR_32];
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (color != LXW_COLOR_UNSET) {
-        lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
-        LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
-    }
-    else {
-        LXW_PUSH_ATTRIBUTES_STR("auto", "1");
-    }
-
-    lxw_xml_empty_tag(self->file, "color", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <border> sub elements such as <right>, <top>, etc.
- */
-STATIC void
-_write_sub_border(lxw_styles *self, const char *type, uint8_t style,
-                  lxw_color_t color)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    char *border_styles[] = {
-        "none",
-        "thin",
-        "medium",
-        "dashed",
-        "dotted",
-        "thick",
-        "double",
-        "hair",
-        "mediumDashed",
-        "dashDot",
-        "mediumDashDot",
-        "dashDotDot",
-        "mediumDashDotDot",
-        "slantDashDot",
-    };
-
-    if (!style) {
-        lxw_xml_empty_tag(self->file, type, NULL);
-        return;
-    }
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("style", border_styles[style]);
-
-    lxw_xml_start_tag(self->file, type, &attributes);
-
-    _write_border_color(self, color);
-
-    lxw_xml_end_tag(self->file, type);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <border> element.
- */
-STATIC void
-_write_border(lxw_styles *self, lxw_format *format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Add attributes for diagonal borders. */
-    if (format->diag_type == LXW_DIAGONAL_BORDER_UP) {
-        LXW_PUSH_ATTRIBUTES_STR("diagonalUp", "1");
-    }
-    else if (format->diag_type == LXW_DIAGONAL_BORDER_DOWN) {
-        LXW_PUSH_ATTRIBUTES_STR("diagonalDown", "1");
-    }
-    else if (format->diag_type == LXW_DIAGONAL_BORDER_UP_DOWN) {
-        LXW_PUSH_ATTRIBUTES_STR("diagonalUp", "1");
-        LXW_PUSH_ATTRIBUTES_STR("diagonalDown", "1");
-    }
-
-    /* Ensure that a default diag border is set if the diag type is set. */
-    if (format->diag_type && !format->diag_border) {
-        format->diag_border = 1;
-    }
-
-    /* Write the start border tag. */
-    lxw_xml_start_tag(self->file, "border", &attributes);
-
-    /* Write the <border> sub elements. */
-    _write_sub_border(self, "left", format->left, format->left_color);
-    _write_sub_border(self, "right", format->right, format->right_color);
-    _write_sub_border(self, "top", format->top, format->top_color);
-    _write_sub_border(self, "bottom", format->bottom, format->bottom_color);
-    _write_sub_border(self,
-                      "diagonal", format->diag_border, format->diag_color);
-
-    lxw_xml_end_tag(self->file, "border");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <borders> element.
- */
-STATIC void
-_write_borders(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_format *format;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", self->border_count);
-
-    lxw_xml_start_tag(self->file, "borders", &attributes);
-
-    STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
-        if (format->has_border)
-            _write_border(self, format);
-    }
-
-    lxw_xml_end_tag(self->file, "borders");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xf> element for styles.
- */
-STATIC void
-_write_style_xf(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("numFmtId", "0");
-    LXW_PUSH_ATTRIBUTES_STR("fontId", "0");
-    LXW_PUSH_ATTRIBUTES_STR("fillId", "0");
-    LXW_PUSH_ATTRIBUTES_STR("borderId", "0");
-
-    lxw_xml_empty_tag(self->file, "xf", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <cellStyleXfs> element.
- */
-STATIC void
-_write_cell_style_xfs(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("count", "1");
-
-    lxw_xml_start_tag(self->file, "cellStyleXfs", &attributes);
-    _write_style_xf(self);
-    lxw_xml_end_tag(self->file, "cellStyleXfs");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Check if a format struct has alignment properties set and the
- * "applyAlignment" attribute should be set.
- */
-STATIC uint8_t
-_apply_alignment(lxw_format *format)
-{
-    return format->text_h_align != LXW_ALIGN_NONE
-        || format->text_v_align != LXW_ALIGN_NONE
-        || format->indent != 0
-        || format->rotation != 0
-        || format->text_wrap != 0
-        || format->shrink != 0 || format->reading_order != 0;
-}
-
-/*
- * Check if a format struct has alignment properties set apart from the
- * LXW_ALIGN_VERTICAL_BOTTOM which Excel treats as a default.
- */
-STATIC uint8_t
-_has_alignment(lxw_format *format)
-{
-    return format->text_h_align != LXW_ALIGN_NONE
-        || !(format->text_v_align == LXW_ALIGN_NONE ||
-             format->text_v_align == LXW_ALIGN_VERTICAL_BOTTOM)
-        || format->indent != 0
-        || format->rotation != 0
-        || format->text_wrap != 0
-        || format->shrink != 0 || format->reading_order != 0;
-}
-
-/*
- * Write the <alignment> element.
- */
-STATIC void
-_write_alignment(lxw_styles *self, lxw_format *format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    int16_t rotation = format->rotation;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Indent is only allowed for horizontal left, right and distributed. */
-    /* If it is defined for any other alignment or no alignment has been  */
-    /* set then default to left alignment. */
-    if (format->indent
-        && format->text_h_align != LXW_ALIGN_LEFT
-        && format->text_h_align != LXW_ALIGN_RIGHT
-        && format->text_h_align != LXW_ALIGN_DISTRIBUTED) {
-        format->text_h_align = LXW_ALIGN_LEFT;
-    }
-
-    /* Check for properties that are mutually exclusive. */
-    if (format->text_wrap)
-        format->shrink = 0;
-
-    if (format->text_h_align == LXW_ALIGN_FILL)
-        format->shrink = 0;
-
-    if (format->text_h_align == LXW_ALIGN_JUSTIFY)
-        format->shrink = 0;
-
-    if (format->text_h_align == LXW_ALIGN_DISTRIBUTED)
-        format->shrink = 0;
-
-    if (format->text_h_align != LXW_ALIGN_DISTRIBUTED)
-        format->just_distrib = 0;
-
-    if (format->indent)
-        format->just_distrib = 0;
-
-    if (format->text_h_align == LXW_ALIGN_LEFT)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "left");
-
-    if (format->text_h_align == LXW_ALIGN_CENTER)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "center");
-
-    if (format->text_h_align == LXW_ALIGN_RIGHT)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "right");
-
-    if (format->text_h_align == LXW_ALIGN_FILL)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "fill");
-
-    if (format->text_h_align == LXW_ALIGN_JUSTIFY)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "justify");
-
-    if (format->text_h_align == LXW_ALIGN_CENTER_ACROSS)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "centerContinuous");
-
-    if (format->text_h_align == LXW_ALIGN_DISTRIBUTED)
-        LXW_PUSH_ATTRIBUTES_STR("horizontal", "distributed");
-
-    if (format->just_distrib)
-        LXW_PUSH_ATTRIBUTES_STR("justifyLastLine", "1");
-
-    if (format->text_v_align == LXW_ALIGN_VERTICAL_TOP)
-        LXW_PUSH_ATTRIBUTES_STR("vertical", "top");
-
-    if (format->text_v_align == LXW_ALIGN_VERTICAL_CENTER)
-        LXW_PUSH_ATTRIBUTES_STR("vertical", "center");
-
-    if (format->text_v_align == LXW_ALIGN_VERTICAL_JUSTIFY)
-        LXW_PUSH_ATTRIBUTES_STR("vertical", "justify");
-
-    if (format->text_v_align == LXW_ALIGN_VERTICAL_DISTRIBUTED)
-        LXW_PUSH_ATTRIBUTES_STR("vertical", "distributed");
-
-    if (format->indent)
-        LXW_PUSH_ATTRIBUTES_INT("indent", format->indent);
-
-    /* Map rotation to Excel values. */
-    if (rotation) {
-        if (rotation == 270)
-            rotation = 255;
-        else if (rotation < 0)
-            rotation = -rotation + 90;
-
-        LXW_PUSH_ATTRIBUTES_INT("textRotation", rotation);
-    }
-
-    if (format->text_wrap)
-        LXW_PUSH_ATTRIBUTES_STR("wrapText", "1");
-
-    if (format->shrink)
-        LXW_PUSH_ATTRIBUTES_STR("shrinkToFit", "1");
-
-    if (format->reading_order == 1)
-        LXW_PUSH_ATTRIBUTES_STR("readingOrder", "1");
-
-    if (format->reading_order == 2)
-        LXW_PUSH_ATTRIBUTES_STR("readingOrder", "2");
-
-    if (!STAILQ_EMPTY(&attributes))
-        lxw_xml_empty_tag(self->file, "alignment", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <protection> element.
- */
-STATIC void
-_write_protection(lxw_styles *self, lxw_format *format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (!format->locked)
-        LXW_PUSH_ATTRIBUTES_STR("locked", "0");
-
-    if (format->hidden)
-        LXW_PUSH_ATTRIBUTES_STR("hidden", "1");
-
-    lxw_xml_empty_tag(self->file, "protection", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <xf> element.
- */
-STATIC void
-_write_xf(lxw_styles *self, lxw_format *format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint8_t has_protection = (!format->locked) | format->hidden;
-    uint8_t has_alignment = _has_alignment(format);
-    uint8_t apply_alignment = _apply_alignment(format);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("numFmtId", format->num_format_index);
-    LXW_PUSH_ATTRIBUTES_INT("fontId", format->font_index);
-    LXW_PUSH_ATTRIBUTES_INT("fillId", format->fill_index);
-    LXW_PUSH_ATTRIBUTES_INT("borderId", format->border_index);
-    LXW_PUSH_ATTRIBUTES_STR("xfId", "0");
-
-    if (format->num_format_index > 0)
-        LXW_PUSH_ATTRIBUTES_STR("applyNumberFormat", "1");
-
-    /* Add applyFont attribute if XF format uses a font element. */
-    if (format->font_index > 0)
-        LXW_PUSH_ATTRIBUTES_STR("applyFont", "1");
-
-    /* Add applyFill attribute if XF format uses a fill element. */
-    if (format->fill_index > 0)
-        LXW_PUSH_ATTRIBUTES_STR("applyFill", "1");
-
-    /* Add applyBorder attribute if XF format uses a border element. */
-    if (format->border_index > 0)
-        LXW_PUSH_ATTRIBUTES_STR("applyBorder", "1");
-
-    /* We can also have applyAlignment without a sub-element. */
-    if (apply_alignment)
-        LXW_PUSH_ATTRIBUTES_STR("applyAlignment", "1");
-
-    if (has_protection)
-        LXW_PUSH_ATTRIBUTES_STR("applyProtection", "1");
-
-    /* Write XF with sub-elements if required. */
-    if (has_alignment || has_protection) {
-        lxw_xml_start_tag(self->file, "xf", &attributes);
-
-        if (has_alignment)
-            _write_alignment(self, format);
-
-        if (has_protection)
-            _write_protection(self, format);
-
-        lxw_xml_end_tag(self->file, "xf");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "xf", &attributes);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <cellXfs> element.
- */
-STATIC void
-_write_cell_xfs(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_format *format;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", self->xf_count);
-
-    lxw_xml_start_tag(self->file, "cellXfs", &attributes);
-
-    STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
-        _write_xf(self, format);
-    }
-
-    lxw_xml_end_tag(self->file, "cellXfs");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <cellStyle> element.
- */
-STATIC void
-_write_cell_style(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("name", "Normal");
-    LXW_PUSH_ATTRIBUTES_STR("xfId", "0");
-    LXW_PUSH_ATTRIBUTES_STR("builtinId", "0");
-
-    lxw_xml_empty_tag(self->file, "cellStyle", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <cellStyles> element.
- */
-STATIC void
-_write_cell_styles(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("count", "1");
-
-    lxw_xml_start_tag(self->file, "cellStyles", &attributes);
-    _write_cell_style(self);
-    lxw_xml_end_tag(self->file, "cellStyles");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <dxfs> element.
- */
-STATIC void
-_write_dxfs(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("count", "0");
-
-    lxw_xml_empty_tag(self->file, "dxfs", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <tableStyles> element.
- */
-STATIC void
-_write_table_styles(lxw_styles *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("count", "0");
-    LXW_PUSH_ATTRIBUTES_STR("defaultTableStyle", "TableStyleMedium9");
-    LXW_PUSH_ATTRIBUTES_STR("defaultPivotStyle", "PivotStyleLight16");
-
-    lxw_xml_empty_tag(self->file, "tableStyles", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_styles_assemble_xml_file(lxw_styles *self)
-{
-    /* Write the XML declaration. */
-    _styles_xml_declaration(self);
-
-    /* Add the style sheet. */
-    _write_style_sheet(self);
-
-    /* Write the number formats. */
-    _write_num_fmts(self);
-
-    /* Write the fonts. */
-    _write_fonts(self);
-
-    /* Write the fills. */
-    _write_fills(self);
-
-    /* Write the borders element. */
-    _write_borders(self);
-
-    /* Write the cellStyleXfs element. */
-    _write_cell_style_xfs(self);
-
-    /* Write the cellXfs element. */
-    _write_cell_xfs(self);
-
-    /* Write the cellStyles element. */
-    _write_cell_styles(self);
-
-    /* Write the dxfs element. */
-    _write_dxfs(self);
-
-    /* Write the tableStyles element. */
-    _write_table_styles(self);
-
-    /* Write the colors element. */
-    /* _write_colors(self); */
-
-    /* Close the style sheet tag. */
-    lxw_xml_end_tag(self->file, "styleSheet");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/

+ 0 - 348
library/src/theme.c

@@ -1,348 +0,0 @@
-/*****************************************************************************
- * theme - A library for creating Excel XLSX theme files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include <string.h>
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/theme.h"
-#include "xlsxwriter/utility.h"
-
-const char *theme_strs[] = {
-    "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n",
-    "<a:theme xmlns:a=\"http://schemas.openxmlformats.org/",
-    "drawingml/2006/main\" name=\"Office Theme\">",
-    "<a:themeElements>",
-    "<a:clrScheme name=\"Office\"><a:dk1>",
-    "<a:sysClr val=\"windowText\" lastClr=\"000000\"/>",
-    "</a:dk1><a:lt1>",
-    "<a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2>",
-    "<a:srgbClr val=\"1F497D\"/></a:dk2><a:lt2>",
-    "<a:srgbClr val=\"EEECE1\"/></a:lt2><a:accent1>",
-    "<a:srgbClr val=\"4F81BD\"/></a:accent1><a:accent2>",
-    "<a:srgbClr val=\"C0504D\"/></a:accent2><a:accent3>",
-    "<a:srgbClr val=\"9BBB59\"/></a:accent3><a:accent4>",
-    "<a:srgbClr val=\"8064A2\"/></a:accent4><a:accent5>",
-    "<a:srgbClr val=\"4BACC6\"/></a:accent5><a:accent6>",
-    "<a:srgbClr val=\"F79646\"/></a:accent6><a:hlink>",
-    "<a:srgbClr val=\"0000FF\"/></a:hlink><a:folHlink>",
-    "<a:srgbClr val=\"800080\"/></a:folHlink></a:clrScheme>",
-    "<a:fontScheme name=\"Office\"><a:majorFont>",
-    "<a:latin typeface=\"Cambria\"/><a:ea typeface=\"\"/>",
-    "<a:cs typeface=\"\"/>",
-    //"<a:font script=\"Jpan\" typeface=\"MSPゴシック\"/>",
-    "<a:font script=\"Hang\" typeface=\"맑은 고딕\"/>",
-    "<a:font script=\"Hans\" typeface=\"宋体\"/>",
-    "<a:font script=\"Hant\" typeface=\"新細明體\"/>",
-    "<a:font script=\"Arab\" typeface=\"Times New Roman\"/>",
-    "<a:font script=\"Hebr\" typeface=\"Times New Roman\"/>",
-    "<a:font script=\"Thai\" typeface=\"Tahoma\"/>",
-    "<a:font script=\"Ethi\" typeface=\"Nyala\"/>",
-    "<a:font script=\"Beng\" typeface=\"Vrinda\"/>",
-    "<a:font script=\"Gujr\" typeface=\"Shruti\"/>",
-    "<a:font script=\"Khmr\" typeface=\"MoolBoran\"/>",
-    "<a:font script=\"Knda\" typeface=\"Tunga\"/>",
-    "<a:font script=\"Guru\" typeface=\"Raavi\"/>",
-    "<a:font script=\"Cans\" typeface=\"Euphemia\"/>",
-    "<a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>",
-    "<a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>",
-    "<a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>",
-    "<a:font script=\"Thaa\" typeface=\"MV Boli\"/>",
-    "<a:font script=\"Deva\" typeface=\"Mangal\"/>",
-    "<a:font script=\"Telu\" typeface=\"Gautami\"/>",
-    "<a:font script=\"Taml\" typeface=\"Latha\"/>",
-    "<a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>",
-    "<a:font script=\"Orya\" typeface=\"Kalinga\"/>",
-    "<a:font script=\"Mlym\" typeface=\"Kartika\"/>",
-    "<a:font script=\"Laoo\" typeface=\"DokChampa\"/>",
-    "<a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>",
-    "<a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>",
-    "<a:font script=\"Viet\" typeface=\"Times New Roman\"/>",
-    "<a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>",
-    "</a:majorFont>",
-    "<a:minorFont>",
-    "<a:latin typeface=\"Calibri\"/>",
-    "<a:ea typeface=\"\"/>",
-    "<a:cs typeface=\"\"/>",
-    //"<a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/>",
-    "<a:font script=\"Hang\" typeface=\"맑은 고딕\"/>",
-    "<a:font script=\"Hans\" typeface=\"宋体\"/>",
-    "<a:font script=\"Hant\" typeface=\"新細明體\"/>",
-    "<a:font script=\"Arab\" typeface=\"Arial\"/>",
-    "<a:font script=\"Hebr\" typeface=\"Arial\"/>",
-    "<a:font script=\"Thai\" typeface=\"Tahoma\"/>",
-    "<a:font script=\"Ethi\" typeface=\"Nyala\"/>",
-    "<a:font script=\"Beng\" typeface=\"Vrinda\"/>",
-    "<a:font script=\"Gujr\" typeface=\"Shruti\"/>",
-    "<a:font script=\"Khmr\" typeface=\"DaunPenh\"/>",
-    "<a:font script=\"Knda\" typeface=\"Tunga\"/>",
-    "<a:font script=\"Guru\" typeface=\"Raavi\"/>",
-    "<a:font script=\"Cans\" typeface=\"Euphemia\"/>",
-    "<a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>",
-    "<a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>",
-    "<a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>",
-    "<a:font script=\"Thaa\" typeface=\"MV Boli\"/>",
-    "<a:font script=\"Deva\" typeface=\"Mangal\"/>",
-    "<a:font script=\"Telu\" typeface=\"Gautami\"/>",
-    "<a:font script=\"Taml\" typeface=\"Latha\"/>",
-    "<a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>",
-    "<a:font script=\"Orya\" typeface=\"Kalinga\"/>",
-    "<a:font script=\"Mlym\" typeface=\"Kartika\"/>",
-    "<a:font script=\"Laoo\" typeface=\"DokChampa\"/>",
-    "<a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>",
-    "<a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>",
-    "<a:font script=\"Viet\" typeface=\"Arial\"/>",
-    "<a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>",
-    "</a:minorFont>",
-    "</a:fontScheme><a:fmtScheme name=\"Office\">",
-    "<a:fillStyleLst>",
-    "<a:solidFill>",
-    "<a:schemeClr val=\"phClr\"/>",
-    "</a:solidFill>",
-    "<a:gradFill rotWithShape=\"1\">",
-    "<a:gsLst>",
-    "<a:gs pos=\"0\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:tint val=\"50000\"/>",
-    "<a:satMod val=\"300000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"35000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:tint val=\"37000\"/>",
-    "<a:satMod val=\"300000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"100000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:tint val=\"15000\"/>",
-    "<a:satMod val=\"350000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "</a:gsLst>",
-    "<a:lin ang=\"16200000\" scaled=\"1\"/>",
-    "</a:gradFill>",
-    "<a:gradFill rotWithShape=\"1\">",
-    "<a:gsLst>",
-    "<a:gs pos=\"0\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:shade val=\"51000\"/>",
-    "<a:satMod val=\"130000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"80000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:shade val=\"93000\"/>",
-    "<a:satMod val=\"130000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"100000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:shade val=\"94000\"/>",
-    "<a:satMod val=\"135000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "</a:gsLst>",
-    "<a:lin ang=\"16200000\" scaled=\"0\"/>",
-    "</a:gradFill>",
-    "</a:fillStyleLst>",
-    "<a:lnStyleLst>",
-    "<a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">",
-    "<a:solidFill>",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:shade val=\"95000\"/>",
-    "<a:satMod val=\"105000\"/>",
-    "</a:schemeClr>",
-    "</a:solidFill>",
-    "<a:prstDash val=\"solid\"/>",
-    "</a:ln>",
-    "<a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">",
-    "<a:solidFill>",
-    "<a:schemeClr val=\"phClr\"/>",
-    "</a:solidFill>",
-    "<a:prstDash val=\"solid\"/>",
-    "</a:ln>",
-    "<a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">",
-    "<a:solidFill>",
-    "<a:schemeClr val=\"phClr\"/>",
-    "</a:solidFill>",
-    "<a:prstDash val=\"solid\"/>",
-    "</a:ln>",
-    "</a:lnStyleLst>",
-    "<a:effectStyleLst>",
-    "<a:effectStyle>",
-    "<a:effectLst>",
-    "<a:outerShdw blurRad=\"40000\" dist=\"20000\" ",
-    "dir=\"5400000\" rotWithShape=\"0\">",
-    "<a:srgbClr val=\"000000\">",
-    "<a:alpha val=\"38000\"/>",
-    "</a:srgbClr>",
-    "</a:outerShdw>",
-    "</a:effectLst>",
-    "</a:effectStyle>",
-    "<a:effectStyle>",
-    "<a:effectLst>",
-    "<a:outerShdw blurRad=\"40000\" dist=\"23000\" ",
-    "dir=\"5400000\" rotWithShape=\"0\">",
-    "<a:srgbClr val=\"000000\">",
-    "<a:alpha val=\"35000\"/>",
-    "</a:srgbClr>",
-    "</a:outerShdw>",
-    "</a:effectLst>",
-    "</a:effectStyle>",
-    "<a:effectStyle>",
-    "<a:effectLst>",
-    "<a:outerShdw blurRad=\"40000\" dist=\"23000\" ",
-    "dir=\"5400000\" rotWithShape=\"0\">",
-    "<a:srgbClr val=\"000000\">",
-    "<a:alpha val=\"35000\"/>",
-    "</a:srgbClr>",
-    "</a:outerShdw>",
-    "</a:effectLst>",
-    "<a:scene3d>",
-    "<a:camera prst=\"orthographicFront\">",
-    "<a:rot lat=\"0\" lon=\"0\" rev=\"0\"/>",
-    "</a:camera>",
-    "<a:lightRig rig=\"threePt\" dir=\"t\">",
-    "<a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/>",
-    "</a:lightRig>",
-    "</a:scene3d>",
-    "<a:sp3d>",
-    "<a:bevelT w=\"63500\" h=\"25400\"/>",
-    "</a:sp3d>",
-    "</a:effectStyle>",
-    "</a:effectStyleLst>",
-    "<a:bgFillStyleLst>",
-    "<a:solidFill>",
-    "<a:schemeClr val=\"phClr\"/>",
-    "</a:solidFill>",
-    "<a:gradFill rotWithShape=\"1\">",
-    "<a:gsLst>",
-    "<a:gs pos=\"0\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:tint val=\"40000\"/>",
-    "<a:satMod val=\"350000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"40000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:tint val=\"45000\"/>",
-    "<a:shade val=\"99000\"/>",
-    "<a:satMod val=\"350000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"100000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:shade val=\"20000\"/>",
-    "<a:satMod val=\"255000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "</a:gsLst>",
-    "<a:path path=\"circle\">",
-    "<a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/>",
-    "</a:path>",
-    "</a:gradFill>",
-    "<a:gradFill rotWithShape=\"1\">",
-    "<a:gsLst>",
-    "<a:gs pos=\"0\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:tint val=\"80000\"/>",
-    "<a:satMod val=\"300000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "<a:gs pos=\"100000\">",
-    "<a:schemeClr val=\"phClr\">",
-    "<a:shade val=\"30000\"/>",
-    "<a:satMod val=\"200000\"/>",
-    "</a:schemeClr>",
-    "</a:gs>",
-    "</a:gsLst>",
-    "<a:path path=\"circle\">",
-    "<a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/>",
-    "</a:path>",
-    "</a:gradFill>",
-    "</a:bgFillStyleLst>",
-    "</a:fmtScheme>",
-    "</a:themeElements>",
-    "<a:objectDefaults/>",
-    "<a:extraClrSchemeLst/>",
-    "</a:theme>\n",
-    ""
-};
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new theme object.
- */
-lxw_theme *
-lxw_theme_new()
-{
-    lxw_theme *theme = calloc(1, sizeof(lxw_theme));
-    GOTO_LABEL_ON_MEM_ERROR(theme, mem_error);
-
-    return theme;
-
-mem_error:
-    lxw_theme_free(theme);
-    return NULL;
-}
-
-/*
- * Free a theme object.
- */
-void
-lxw_theme_free(lxw_theme *theme)
-{
-    if (!theme)
-        return;
-
-    free(theme);
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/* This library isn't a xmlwriter. */
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_theme_assemble_xml_file(lxw_theme *self)
-{
-    int i = 0;
-
-    while (strlen(theme_strs[i])) {
-        fprintf(self->file, "%s", theme_strs[i]);
-        i++;
-    }
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/

+ 0 - 555
library/src/utility.c

@@ -1,555 +0,0 @@
-/*****************************************************************************
- * utility - Utility functions for libxlsxwriter.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include "xlsxwriter/utility.h"
-#include "xlsxwriter/third_party/tmpfileplus.h"
-
-char *error_strings[LXW_MAX_ERRNO + 1] = {
-    "No error.",
-    "Memory error, failed to malloc() required memory.",
-    "Error creating output xlsx file. Usually a permissions error.",
-    "Error encountered when creating a tmpfile during file assembly.",
-    "Zlib error with a file operation while creating xlsx file.",
-    "Zlib error when adding sub file to xlsx file.",
-    "Zlib error when closing xlsx file.",
-    "NULL function parameter ignored.",
-    "Function parameter validation error.",
-    "Worksheet name exceeds Excel's limit of 31 characters.",
-    "Worksheet name contains invalid Excel character: '[]:*?/\\'",
-    "Worksheet name is already in use.",
-    "Parameter exceeds Excel's limit of 32 characters.",
-    "Parameter exceeds Excel's limit of 128 characters.",
-    "Parameter exceeds Excel's limit of 255 characters.",
-    "String exceeds Excel's limit of 32,767 characters.",
-    "Error finding internal string index.",
-    "Worksheet row or column index out of range.",
-    "Maximum number of worksheet URLs (65530) exceeded.",
-    "Couldn't read image dimensions or DPI.",
-    "Unknown error number."
-};
-
-char *
-lxw_strerror(lxw_error error_num)
-{
-    if (error_num > LXW_MAX_ERRNO)
-        error_num = LXW_MAX_ERRNO;
-
-    return error_strings[error_num];
-}
-
-/*
- * Convert Excel A-XFD style column name to zero based number.
- */
-void
-lxw_col_to_name(char *col_name, lxw_col_t col_num, uint8_t absolute)
-{
-    uint8_t pos = 0;
-    size_t len;
-    uint8_t i;
-
-    /* Change from 0 index to 1 index. */
-    col_num++;
-
-    /* Convert the column number to a string in reverse order. */
-    while (col_num) {
-
-        /* Get the remainder in base 26. */
-        int remainder = col_num % 26;
-
-        if (remainder == 0)
-            remainder = 26;
-
-        /* Convert the remainder value to a character. */
-        col_name[pos++] = 'A' + remainder - 1;
-        col_name[pos] = '\0';
-
-        /* Get the next order of magnitude. */
-        col_num = (col_num - 1) / 26;
-    }
-
-    if (absolute) {
-        col_name[pos] = '$';
-        col_name[pos + 1] = '\0';
-    }
-
-    /* Reverse the column name string. */
-    len = strlen(col_name);
-    for (i = 0; i < (len / 2); i++) {
-        char tmp = col_name[i];
-        col_name[i] = col_name[len - i - 1];
-        col_name[len - i - 1] = tmp;
-    }
-}
-
-/*
- * Convert zero indexed row and column to an Excel style A1 cell reference.
- */
-void
-lxw_rowcol_to_cell(char *cell_name, lxw_row_t row, lxw_col_t col)
-{
-    size_t pos;
-
-    /* Add the column to the cell. */
-    lxw_col_to_name(cell_name, col, 0);
-
-    /* Get the end of the cell. */
-    pos = strlen(cell_name);
-
-    /* Add the row to the cell. */
-    lxw_snprintf(&cell_name[pos], LXW_MAX_ROW_NAME_LENGTH, "%d", ++row);
-}
-
-/*
- * Convert zero indexed row and column to an Excel style $A$1 cell with
- * an absolute reference.
- */
-void
-lxw_rowcol_to_cell_abs(char *cell_name, lxw_row_t row, lxw_col_t col,
-                       uint8_t abs_row, uint8_t abs_col)
-{
-    size_t pos;
-
-    /* Add the column to the cell. */
-    lxw_col_to_name(cell_name, col, abs_col);
-
-    /* Get the end of the cell. */
-    pos = strlen(cell_name);
-
-    if (abs_row)
-        cell_name[pos++] = '$';
-
-    /* Add the row to the cell. */
-    lxw_snprintf(&cell_name[pos], LXW_MAX_ROW_NAME_LENGTH, "%d", ++row);
-}
-
-/*
- * Convert zero indexed row and column pair to an Excel style A1:C5
- * range reference.
- */
-void
-lxw_rowcol_to_range(char *range,
-                    lxw_row_t first_row, lxw_col_t first_col,
-                    lxw_row_t last_row, lxw_col_t last_col)
-{
-    size_t pos;
-
-    /* Add the first cell to the range. */
-    lxw_rowcol_to_cell(range, first_row, first_col);
-
-    /* If the start and end cells are the same just return a single cell. */
-    if (first_row == last_row && first_col == last_col)
-        return;
-
-    /* Get the end of the cell. */
-    pos = strlen(range);
-
-    /* Add the range separator. */
-    range[pos++] = ':';
-
-    /* Add the first cell to the range. */
-    lxw_rowcol_to_cell(&range[pos], last_row, last_col);
-}
-
-/*
- * Convert zero indexed row and column pairs to an Excel style $A$1:$C$5
- * range reference with absolute values.
- */
-void
-lxw_rowcol_to_range_abs(char *range,
-                        lxw_row_t first_row, lxw_col_t first_col,
-                        lxw_row_t last_row, lxw_col_t last_col)
-{
-    size_t pos;
-
-    /* Add the first cell to the range. */
-    lxw_rowcol_to_cell_abs(range, first_row, first_col, 1, 1);
-
-    /* If the start and end cells are the same just return a single cell. */
-    if (first_row == last_row && first_col == last_col)
-        return;
-
-    /* Get the end of the cell. */
-    pos = strlen(range);
-
-    /* Add the range separator. */
-    range[pos++] = ':';
-
-    /* Add the first cell to the range. */
-    lxw_rowcol_to_cell_abs(&range[pos], last_row, last_col, 1, 1);
-}
-
-/*
- * Convert sheetname and zero indexed row and column pairs to an Excel style
- * Sheet1!$A$1:$C$5 formula reference with absolute values.
- */
-void
-lxw_rowcol_to_formula_abs(char *formula, const char *sheetname,
-                          lxw_row_t first_row, lxw_col_t first_col,
-                          lxw_row_t last_row, lxw_col_t last_col)
-{
-    size_t pos;
-    char *quoted_name = lxw_quote_sheetname(sheetname);
-
-    strncpy(formula, quoted_name, LXW_MAX_FORMULA_RANGE_LENGTH - 1);
-    free(quoted_name);
-
-    /* Get the end of the sheetname. */
-    pos = strlen(formula);
-
-    /* Add the range separator. */
-    formula[pos++] = '!';
-
-    /* Add the first cell to the range. */
-    lxw_rowcol_to_cell_abs(&formula[pos], first_row, first_col, 1, 1);
-
-    /* If the start and end cells are the same just return a single cell. */
-    if (first_row == last_row && first_col == last_col)
-        return;
-
-    /* Get the end of the cell. */
-    pos = strlen(formula);
-
-    /* Add the range separator. */
-    formula[pos++] = ':';
-
-    /* Add the first cell to the range. */
-    lxw_rowcol_to_cell_abs(&formula[pos], last_row, last_col, 1, 1);
-}
-
-/*
- * Convert an Excel style A1 cell reference to a zero indexed row number.
- */
-lxw_row_t
-lxw_name_to_row(const char *row_str)
-{
-    lxw_row_t row_num = 0;
-    const char *p = row_str;
-
-    /* Skip the column letters and absolute symbol of the A1 cell. */
-    while (p && !isdigit((unsigned char) *p))
-        p++;
-
-    /* Convert the row part of the A1 cell to a number. */
-    if (p)
-        row_num = atoi(p);
-
-    if (row_num)
-        return row_num - 1;
-    else
-        return 0;
-}
-
-/*
- * Convert an Excel style A1 cell reference to a zero indexed column number.
- */
-lxw_col_t
-lxw_name_to_col(const char *col_str)
-{
-    lxw_col_t col_num = 0;
-    const char *p = col_str;
-
-    /* Convert leading column letters of A1 cell. Ignore absolute $ marker. */
-    while (p && (isupper((unsigned char) *p) || *p == '$')) {
-        if (*p != '$')
-            col_num = (col_num * 26) + (*p - 'A' + 1);
-        p++;
-    }
-
-    return col_num - 1;
-}
-
-/*
- * Convert the second row of an Excel range ref to a zero indexed number.
- */
-uint32_t
-lxw_name_to_row_2(const char *row_str)
-{
-    const char *p = row_str;
-
-    /* Find the : separator in the range. */
-    while (p && *p != ':')
-        p++;
-
-    if (p)
-        return lxw_name_to_row(++p);
-    else
-        return -1;
-}
-
-/*
- * Convert the second column of an Excel range ref to a zero indexed number.
- */
-uint16_t
-lxw_name_to_col_2(const char *col_str)
-{
-    const char *p = col_str;
-
-    /* Find the : separator in the range. */
-    while (p && *p != ':')
-        p++;
-
-    if (p)
-        return lxw_name_to_col(++p);
-    else
-        return -1;
-}
-
-/*
- * Convert a lxw_datetime struct to an Excel serial date.
- */
-double
-lxw_datetime_to_excel_date(lxw_datetime *datetime, uint8_t date_1904)
-{
-    int year = datetime->year;
-    int month = datetime->month;
-    int day = datetime->day;
-    int hour = datetime->hour;
-    int min = datetime->min;
-    double sec = datetime->sec;
-    double seconds;
-    int epoch = date_1904 ? 1904 : 1900;
-    int offset = date_1904 ? 4 : 0;
-    int norm = 300;
-    int range;
-    /* Set month days and check for leap year. */
-    int mdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-    int leap = 0;
-    int days = 0;
-    int i;
-
-    /* For times without dates set the default date for the epoch. */
-    if (!year) {
-        if (!date_1904) {
-            year = 1899;
-            month = 12;
-            day = 31;
-        }
-        else {
-            year = 1904;
-            month = 1;
-            day = 1;
-        }
-    }
-
-    /* Convert the Excel seconds to a fraction of the seconds in 24 hours. */
-    seconds = (hour * 60 * 60 + min * 60 + sec) / (24 * 60 * 60.0);
-
-    /* Special cases for Excel dates in the 1900 epoch. */
-    if (!date_1904) {
-        /* Excel 1900 epoch. */
-        if (year == 1899 && month == 12 && day == 31)
-            return seconds;
-
-        /* Excel 1900 epoch. */
-        if (year == 1900 && month == 1 && day == 0)
-            return seconds;
-
-        /* Excel false leapday */
-        if (year == 1900 && month == 2 && day == 29)
-            return 60 + seconds;
-    }
-
-    /* We calculate the date by calculating the number of days since the */
-    /* epoch and adjust for the number of leap days. We calculate the */
-    /* number of leap days by normalizing the year in relation to the */
-    /* epoch. Thus the year 2000 becomes 100 for 4-year and 100-year */
-    /* leapdays and 400 for 400-year leapdays. */
-    range = year - epoch;
-
-    if (year % 4 == 0 && (year % 100 > 0 || year % 400 == 0)) {
-        leap = 1;
-        mdays[2] = 29;
-    }
-
-    /*
-     * Calculate the serial date by accumulating the number of days
-     * since the epoch.
-     */
-
-    /* Add days for previous months. */
-    for (i = 0; i < month; i++) {
-        days += mdays[i];
-    }
-    /* Add days for current month. */
-    days += day;
-    /* Add days for all previous years.  */
-    days += range * 365;
-    /* Add 4 year leapdays. */
-    days += (range) / 4;
-    /* Remove 100 year leapdays. */
-    days -= (range + offset) / 100;
-    /* Add 400 year leapdays. */
-    days += (range + offset + norm) / 400;
-    /* Remove leap days already counted. */
-    days -= leap;
-
-    /* Adjust for Excel erroneously treating 1900 as a leap year. */
-    if (!date_1904 && days > 59)
-        days++;
-
-    return days + seconds;
-}
-
-/* Simple strdup() implementation since it isn't ANSI C. */
-char *
-lxw_strdup(const char *str)
-{
-    size_t len;
-    char *copy;
-
-    if (!str)
-        return NULL;
-
-    len = strlen(str) + 1;
-    copy = malloc(len);
-
-    if (copy)
-        memcpy(copy, str, len);
-
-    return copy;
-}
-
-/* Simple function to strdup() a formula string without the leading "=". */
-char *
-lxw_strdup_formula(const char *formula)
-{
-    if (!formula)
-        return NULL;
-
-    if (formula[0] == '=')
-        return lxw_strdup(formula + 1);
-    else
-        return lxw_strdup(formula);
-}
-
-/* Simple strlen that counts UTF-8 characters. Assumes well formed UTF-8. */
-size_t
-lxw_utf8_strlen(const char *str)
-{
-    size_t byte_count = 0;
-    size_t char_count = 0;
-
-    while (str[byte_count]) {
-        if ((str[byte_count] & 0xc0) != 0x80)
-            char_count++;
-
-        byte_count++;
-    }
-
-    return char_count;
-}
-
-/* Simple tolower() for strings. */
-void
-lxw_str_tolower(char *str)
-{
-    int i;
-
-    for (i = 0; str[i]; i++)
-        str[i] = tolower(str[i]);
-}
-
-/* Create a quoted version of the worksheet name, or return an unmodified
- * copy if it doesn't required quoting. */
-char *
-lxw_quote_sheetname(const char *str)
-{
-
-    uint8_t needs_quoting = 0;
-    size_t number_of_quotes = 2;
-    size_t i, j;
-    size_t len = strlen(str);
-
-    /* Don't quote the sheetname if it is already quoted. */
-    if (str[0] == '\'')
-        return lxw_strdup(str);
-
-    /* Check if the sheetname contains any characters that require it
-     * to be quoted. Also check for single quotes within the string. */
-    for (i = 0; i < len; i++) {
-        if (!isalnum((unsigned char) str[i]) && str[i] != '_'
-            && str[i] != '.')
-            needs_quoting = 1;
-
-        if (str[i] == '\'') {
-            needs_quoting = 1;
-            number_of_quotes++;
-        }
-    }
-
-    if (!needs_quoting) {
-        return lxw_strdup(str);
-    }
-    else {
-        /* Add single quotes to the start and end of the string. */
-        char *quoted_name = calloc(1, len + number_of_quotes + 1);
-        RETURN_ON_MEM_ERROR(quoted_name, NULL);
-
-        quoted_name[0] = '\'';
-
-        for (i = 0, j = 1; i < len; i++, j++) {
-            quoted_name[j] = str[i];
-
-            /* Double quote inline single quotes. */
-            if (str[i] == '\'') {
-                quoted_name[++j] = '\'';
-            }
-        }
-        quoted_name[j++] = '\'';
-        quoted_name[j++] = '\0';
-
-        return quoted_name;
-    }
-}
-
-/*
- * Thin wrapper for tmpfile() so it can be over-ridden with a user defined
- * version if required for safety or portability.
- */
-FILE *
-lxw_tmpfile(char *tmpdir)
-{
-#ifndef USE_STANDARD_TMPFILE
-    return tmpfileplus(tmpdir, NULL, NULL, 0);
-#else
-    (void) tmpdir;
-    return tmpfile();
-#endif
-}
-
-/*
- * Sample function to handle sprintf of doubles for locale portable code. This
- * is usually handled by a lxw_sprintf_dbl() macro but it can be replaced with
- * a function of the same name.
- *
- * The code below is a simplified example that changes numbers like 123,45 to
- * 123.45. End-users can replace this with something more rigorous if
- * required.
- */
-#ifdef USE_DOUBLE_FUNCTION
-int
-lxw_sprintf_dbl(char *data, double number)
-{
-    char *tmp;
-
-    lxw_snprintf(data, LXW_ATTR_32, "%.16g", number);
-
-    /* Replace comma with decimal point. */
-    tmp = strchr(data, ',');
-    if (tmp)
-        *tmp = '.';
-
-    return 0;
-}
-#endif

+ 0 - 1913
library/src/workbook.c

@@ -1,1913 +0,0 @@
-/*****************************************************************************
- * workbook - A library for creating Excel XLSX workbook files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/workbook.h"
-#include "xlsxwriter/utility.h"
-#include "xlsxwriter/packager.h"
-#include "xlsxwriter/hash_table.h"
-
-STATIC int _name_cmp(lxw_worksheet_name *name1, lxw_worksheet_name *name2);
-#ifndef __clang_analyzer__
-LXW_RB_GENERATE_NAMES(lxw_worksheet_names, lxw_worksheet_name, tree_pointers,
-                      _name_cmp);
-#endif
-
-/*
- * Forward declarations.
- */
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Comparator for the worksheet names structure red/black tree.
- */
-STATIC int
-_name_cmp(lxw_worksheet_name *name1, lxw_worksheet_name *name2)
-{
-    return strcmp(name1->name, name2->name);
-}
-
-/*
- * Free workbook properties.
- */
-STATIC void
-_free_doc_properties(lxw_doc_properties *properties)
-{
-    if (properties) {
-        free(properties->title);
-        free(properties->subject);
-        free(properties->author);
-        free(properties->manager);
-        free(properties->company);
-        free(properties->category);
-        free(properties->keywords);
-        free(properties->comments);
-        free(properties->status);
-        free(properties->hyperlink_base);
-    }
-
-    free(properties);
-}
-
-/*
- * Free workbook custom property.
- */
-STATIC void
-_free_custom_doc_property(lxw_custom_property *custom_property)
-{
-    if (custom_property) {
-        free(custom_property->name);
-        if (custom_property->type == LXW_CUSTOM_STRING)
-            free(custom_property->u.string);
-    }
-
-    free(custom_property);
-}
-
-/*
- * Free a workbook object.
- */
-void
-lxw_workbook_free(lxw_workbook *workbook)
-{
-    lxw_worksheet *worksheet;
-    struct lxw_worksheet_name *worksheet_name;
-    struct lxw_worksheet_name *next_name;
-    lxw_chart *chart;
-    lxw_format *format;
-    lxw_defined_name *defined_name;
-    lxw_defined_name *defined_name_tmp;
-    lxw_custom_property *custom_property;
-
-    if (!workbook)
-        return;
-
-    _free_doc_properties(workbook->properties);
-
-    free(workbook->filename);
-
-    /* Free the worksheets in the workbook. */
-    if (workbook->worksheets) {
-        while (!STAILQ_EMPTY(workbook->worksheets)) {
-            worksheet = STAILQ_FIRST(workbook->worksheets);
-            STAILQ_REMOVE_HEAD(workbook->worksheets, list_pointers);
-            lxw_worksheet_free(worksheet);
-        }
-        free(workbook->worksheets);
-
-    }
-
-    /* Free the charts in the workbook. */
-    if (workbook->charts) {
-        while (!STAILQ_EMPTY(workbook->charts)) {
-            chart = STAILQ_FIRST(workbook->charts);
-            STAILQ_REMOVE_HEAD(workbook->charts, list_pointers);
-            lxw_chart_free(chart);
-        }
-        free(workbook->charts);
-    }
-
-    /* Free the formats in the workbook. */
-    if (workbook->formats) {
-        while (!STAILQ_EMPTY(workbook->formats)) {
-            format = STAILQ_FIRST(workbook->formats);
-            STAILQ_REMOVE_HEAD(workbook->formats, list_pointers);
-            lxw_format_free(format);
-        }
-        free(workbook->formats);
-    }
-
-    /* Free the defined_names in the workbook. */
-    if (workbook->defined_names) {
-        defined_name = TAILQ_FIRST(workbook->defined_names);
-        while (defined_name) {
-
-            defined_name_tmp = TAILQ_NEXT(defined_name, list_pointers);
-            free(defined_name);
-            defined_name = defined_name_tmp;
-        }
-        free(workbook->defined_names);
-    }
-
-    /* Free the custom_properties in the workbook. */
-    if (workbook->custom_properties) {
-        while (!STAILQ_EMPTY(workbook->custom_properties)) {
-            custom_property = STAILQ_FIRST(workbook->custom_properties);
-            STAILQ_REMOVE_HEAD(workbook->custom_properties, list_pointers);
-            _free_custom_doc_property(custom_property);
-        }
-        free(workbook->custom_properties);
-    }
-
-    if (workbook->worksheet_names) {
-        for (worksheet_name =
-             RB_MIN(lxw_worksheet_names, workbook->worksheet_names);
-             worksheet_name; worksheet_name = next_name) {
-
-            next_name = RB_NEXT(lxw_worksheet_names,
-                                workbook->worksheet_name, worksheet_name);
-            RB_REMOVE(lxw_worksheet_names,
-                      workbook->worksheet_names, worksheet_name);
-            free(worksheet_name);
-        }
-
-        free(workbook->worksheet_names);
-    }
-
-    lxw_hash_free(workbook->used_xf_formats);
-    lxw_sst_free(workbook->sst);
-    free(workbook->options.tmpdir);
-    free(workbook->ordered_charts);
-    free(workbook);
-}
-
-/*
- * Set the default index for each format. This is only used for testing.
- */
-void
-lxw_workbook_set_default_xf_indices(lxw_workbook *self)
-{
-    lxw_format *format;
-
-    STAILQ_FOREACH(format, self->formats, list_pointers) {
-        lxw_format_get_xf_index(format);
-    }
-}
-
-/*
- * Iterate through the XF Format objects and give them an index to non-default
- * font elements.
- */
-STATIC void
-_prepare_fonts(lxw_workbook *self)
-{
-
-    lxw_hash_table *fonts = lxw_hash_new(128, 1, 1);
-    lxw_hash_element *hash_element;
-    lxw_hash_element *used_format_element;
-    uint16_t index = 0;
-
-    LXW_FOREACH_ORDERED(used_format_element, self->used_xf_formats) {
-        lxw_format *format = (lxw_format *) used_format_element->value;
-        lxw_font *key = lxw_format_get_font_key(format);
-
-        if (key) {
-            /* Look up the format in the hash table. */
-            hash_element = lxw_hash_key_exists(fonts, key, sizeof(lxw_font));
-
-            if (hash_element) {
-                /* Font has already been used. */
-                format->font_index = *(uint16_t *) hash_element->value;
-                format->has_font = LXW_FALSE;
-                free(key);
-            }
-            else {
-                /* This is a new font. */
-                uint16_t *font_index = calloc(1, sizeof(uint16_t));
-                *font_index = index;
-                format->font_index = index;
-                format->has_font = 1;
-                lxw_insert_hash_element(fonts, key, font_index,
-                                        sizeof(lxw_font));
-                index++;
-            }
-        }
-    }
-
-    lxw_hash_free(fonts);
-
-    self->font_count = index;
-}
-
-/*
- * Iterate through the XF Format objects and give them an index to non-default
- * border elements.
- */
-STATIC void
-_prepare_borders(lxw_workbook *self)
-{
-
-    lxw_hash_table *borders = lxw_hash_new(128, 1, 1);
-    lxw_hash_element *hash_element;
-    lxw_hash_element *used_format_element;
-    uint16_t index = 0;
-
-    LXW_FOREACH_ORDERED(used_format_element, self->used_xf_formats) {
-        lxw_format *format = (lxw_format *) used_format_element->value;
-        lxw_border *key = lxw_format_get_border_key(format);
-
-        if (key) {
-            /* Look up the format in the hash table. */
-            hash_element =
-                lxw_hash_key_exists(borders, key, sizeof(lxw_border));
-
-            if (hash_element) {
-                /* Border has already been used. */
-                format->border_index = *(uint16_t *) hash_element->value;
-                format->has_border = LXW_FALSE;
-                free(key);
-            }
-            else {
-                /* This is a new border. */
-                uint16_t *border_index = calloc(1, sizeof(uint16_t));
-                *border_index = index;
-                format->border_index = index;
-                format->has_border = 1;
-                lxw_insert_hash_element(borders, key, border_index,
-                                        sizeof(lxw_border));
-                index++;
-            }
-        }
-    }
-
-    lxw_hash_free(borders);
-
-    self->border_count = index;
-}
-
-/*
- * Iterate through the XF Format objects and give them an index to non-default
- * fill elements.
- */
-STATIC void
-_prepare_fills(lxw_workbook *self)
-{
-
-    lxw_hash_table *fills = lxw_hash_new(128, 1, 1);
-    lxw_hash_element *hash_element;
-    lxw_hash_element *used_format_element;
-    uint16_t index = 2;
-    lxw_fill *default_fill_1 = NULL;
-    lxw_fill *default_fill_2 = NULL;
-    uint16_t *fill_index1 = NULL;
-    uint16_t *fill_index2 = NULL;
-
-    default_fill_1 = calloc(1, sizeof(lxw_fill));
-    GOTO_LABEL_ON_MEM_ERROR(default_fill_1, mem_error);
-
-    default_fill_2 = calloc(1, sizeof(lxw_fill));
-    GOTO_LABEL_ON_MEM_ERROR(default_fill_2, mem_error);
-
-    fill_index1 = calloc(1, sizeof(uint16_t));
-    GOTO_LABEL_ON_MEM_ERROR(fill_index1, mem_error);
-
-    fill_index2 = calloc(1, sizeof(uint16_t));
-    GOTO_LABEL_ON_MEM_ERROR(fill_index2, mem_error);
-
-    /* Add the default fills. */
-    default_fill_1->pattern = LXW_PATTERN_NONE;
-    default_fill_1->fg_color = LXW_COLOR_UNSET;
-    default_fill_1->bg_color = LXW_COLOR_UNSET;
-    *fill_index1 = 0;
-    lxw_insert_hash_element(fills, default_fill_1, fill_index1,
-                            sizeof(lxw_fill));
-
-    default_fill_2->pattern = LXW_PATTERN_GRAY_125;
-    default_fill_2->fg_color = LXW_COLOR_UNSET;
-    default_fill_2->bg_color = LXW_COLOR_UNSET;
-    *fill_index2 = 1;
-    lxw_insert_hash_element(fills, default_fill_2, fill_index2,
-                            sizeof(lxw_fill));
-
-    LXW_FOREACH_ORDERED(used_format_element, self->used_xf_formats) {
-        lxw_format *format = (lxw_format *) used_format_element->value;
-        lxw_fill *key = lxw_format_get_fill_key(format);
-
-        /* The following logical statements jointly take care of special */
-        /* cases in relation to cell colors and patterns:                */
-        /* 1. For a solid fill (pattern == 1) Excel reverses the role of */
-        /*    foreground and background colors, and                      */
-        /* 2. If the user specifies a foreground or background color     */
-        /*    without a pattern they probably wanted a solid fill, so    */
-        /*    we fill in the defaults.                                   */
-        if (format->pattern == LXW_PATTERN_SOLID
-            && format->bg_color != LXW_COLOR_UNSET
-            && format->fg_color != LXW_COLOR_UNSET) {
-            lxw_color_t tmp = format->fg_color;
-            format->fg_color = format->bg_color;
-            format->bg_color = tmp;
-        }
-
-        if (format->pattern <= LXW_PATTERN_SOLID
-            && format->bg_color != LXW_COLOR_UNSET
-            && format->fg_color == LXW_COLOR_UNSET) {
-            format->fg_color = format->bg_color;
-            format->bg_color = LXW_COLOR_UNSET;
-            format->pattern = LXW_PATTERN_SOLID;
-        }
-
-        if (format->pattern <= LXW_PATTERN_SOLID
-            && format->bg_color == LXW_COLOR_UNSET
-            && format->fg_color != LXW_COLOR_UNSET) {
-            format->bg_color = LXW_COLOR_UNSET;
-            format->pattern = LXW_PATTERN_SOLID;
-        }
-
-        if (key) {
-            /* Look up the format in the hash table. */
-            hash_element = lxw_hash_key_exists(fills, key, sizeof(lxw_fill));
-
-            if (hash_element) {
-                /* Fill has already been used. */
-                format->fill_index = *(uint16_t *) hash_element->value;
-                format->has_fill = LXW_FALSE;
-                free(key);
-            }
-            else {
-                /* This is a new fill. */
-                uint16_t *fill_index = calloc(1, sizeof(uint16_t));
-                *fill_index = index;
-                format->fill_index = index;
-                format->has_fill = 1;
-                lxw_insert_hash_element(fills, key, fill_index,
-                                        sizeof(lxw_fill));
-                index++;
-            }
-        }
-    }
-
-    lxw_hash_free(fills);
-
-    self->fill_count = index;
-
-    return;
-
-mem_error:
-    free(fill_index2);
-    free(fill_index1);
-    free(default_fill_2);
-    free(default_fill_1);
-    lxw_hash_free(fills);
-}
-
-/*
- * Iterate through the XF Format objects and give them an index to non-default
- * number format elements. Note, user defined records start from index 0xA4.
- */
-STATIC void
-_prepare_num_formats(lxw_workbook *self)
-{
-
-    lxw_hash_table *num_formats = lxw_hash_new(128, 0, 1);
-    lxw_hash_element *hash_element;
-    lxw_hash_element *used_format_element;
-    uint16_t index = 0xA4;
-    uint16_t num_format_count = 0;
-    uint16_t *num_format_index;
-
-    LXW_FOREACH_ORDERED(used_format_element, self->used_xf_formats) {
-        lxw_format *format = (lxw_format *) used_format_element->value;
-
-        /* Format already has a number format index. */
-        if (format->num_format_index)
-            continue;
-
-        /* Check if there is a user defined number format string. */
-        if (*format->num_format) {
-            char num_format[LXW_FORMAT_FIELD_LEN] = { 0 };
-            lxw_snprintf(num_format, LXW_FORMAT_FIELD_LEN, "%s",
-                         format->num_format);
-
-            /* Look up the num_format in the hash table. */
-            hash_element = lxw_hash_key_exists(num_formats, num_format,
-                                               LXW_FORMAT_FIELD_LEN);
-
-            if (hash_element) {
-                /* Num_Format has already been used. */
-                format->num_format_index = *(uint16_t *) hash_element->value;
-            }
-            else {
-                /* This is a new num_format. */
-                num_format_index = calloc(1, sizeof(uint16_t));
-                *num_format_index = index;
-                format->num_format_index = index;
-                lxw_insert_hash_element(num_formats, num_format,
-                                        num_format_index,
-                                        LXW_FORMAT_FIELD_LEN);
-                index++;
-                num_format_count++;
-            }
-        }
-    }
-
-    lxw_hash_free(num_formats);
-
-    self->num_format_count = num_format_count;
-}
-
-/*
- * Prepare workbook and sub-objects for writing.
- */
-STATIC void
-_prepare_workbook(lxw_workbook *self)
-{
-    /* Set the font index for the format objects. */
-    _prepare_fonts(self);
-
-    /* Set the number format index for the format objects. */
-    _prepare_num_formats(self);
-
-    /* Set the border index for the format objects. */
-    _prepare_borders(self);
-
-    /* Set the fill index for the format objects. */
-    _prepare_fills(self);
-
-}
-
-/*
- * Compare two defined_name structures.
- */
-static int
-_compare_defined_names(lxw_defined_name *a, lxw_defined_name *b)
-{
-    int res = strcmp(a->normalised_name, b->normalised_name);
-
-    /* Primary comparison based on defined name. */
-    if (res)
-        return res;
-
-    /* Secondary comparison based on worksheet name. */
-    res = strcmp(a->normalised_sheetname, b->normalised_sheetname);
-
-    return res;
-}
-
-/*
- * Process and store the defined names. The defined names are stored with
- * the Workbook.xml but also with the App.xml if they refer to a sheet
- * range like "Sheet1!:A1". The defined names are store in sorted
- * order for consistency with Excel. The names need to be normalized before
- * sorting.
- */
-STATIC lxw_error
-_store_defined_name(lxw_workbook *self, const char *name,
-                    const char *app_name, const char *formula, int16_t index,
-                    uint8_t hidden)
-{
-    lxw_worksheet *worksheet;
-    lxw_defined_name *defined_name;
-    lxw_defined_name *list_defined_name;
-    char name_copy[LXW_DEFINED_NAME_LENGTH];
-    char *tmp_str;
-    char *worksheet_name;
-
-    /* Do some checks on the input data */
-    if (!name || !formula)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    if (lxw_utf8_strlen(name) > LXW_DEFINED_NAME_LENGTH ||
-        lxw_utf8_strlen(formula) > LXW_DEFINED_NAME_LENGTH) {
-        return LXW_ERROR_128_STRING_LENGTH_EXCEEDED;
-    }
-
-    /* Allocate a new defined_name to be added to the linked list of names. */
-    defined_name = calloc(1, sizeof(struct lxw_defined_name));
-    RETURN_ON_MEM_ERROR(defined_name, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    /* Copy the user input string. */
-    lxw_strcpy(name_copy, name);
-
-    /* Set the worksheet index or -1 for a global defined name. */
-    defined_name->index = index;
-    defined_name->hidden = hidden;
-
-    /* Check for local defined names like like "Sheet1!name". */
-    tmp_str = strchr(name_copy, '!');
-
-    if (tmp_str == NULL) {
-        /* The name is global. We just store the defined name string. */
-        lxw_strcpy(defined_name->name, name_copy);
-    }
-    else {
-        /* The name is worksheet local. We need to extract the sheet name
-         * and map it to a sheet index. */
-
-        /* Split the into the worksheet name and defined name. */
-        *tmp_str = '\0';
-        tmp_str++;
-        worksheet_name = name_copy;
-
-        /* Remove any worksheet quoting. */
-        if (worksheet_name[0] == '\'')
-            worksheet_name++;
-        if (worksheet_name[strlen(worksheet_name) - 1] == '\'')
-            worksheet_name[strlen(worksheet_name) - 1] = '\0';
-
-        /* Search for worksheet name to get the equivalent worksheet index. */
-        STAILQ_FOREACH(worksheet, self->worksheets, list_pointers) {
-            if (strcmp(worksheet_name, worksheet->name) == 0) {
-                defined_name->index = worksheet->index;
-                lxw_strcpy(defined_name->normalised_sheetname,
-                           worksheet_name);
-            }
-        }
-
-        /* If we didn't find the worksheet name we exit. */
-        if (defined_name->index == -1)
-            goto mem_error;
-
-        lxw_strcpy(defined_name->name, tmp_str);
-    }
-
-    /* Print titles and repeat title pass in the name used for App.xml. */
-    if (app_name) {
-        lxw_strcpy(defined_name->app_name, app_name);
-        lxw_strcpy(defined_name->normalised_sheetname, app_name);
-    }
-    else {
-        lxw_strcpy(defined_name->app_name, name);
-    }
-
-    /* We need to normalize the defined names for sorting. This involves
-     * removing any _xlnm namespace  and converting it to lowercase. */
-    tmp_str = strstr(name_copy, "_xlnm.");
-
-    if (tmp_str)
-        lxw_strcpy(defined_name->normalised_name, defined_name->name + 6);
-    else
-        lxw_strcpy(defined_name->normalised_name, defined_name->name);
-
-    lxw_str_tolower(defined_name->normalised_name);
-    lxw_str_tolower(defined_name->normalised_sheetname);
-
-    /* Strip leading "=" from the formula. */
-    if (formula[0] == '=')
-        lxw_strcpy(defined_name->formula, formula + 1);
-    else
-        lxw_strcpy(defined_name->formula, formula);
-
-    /* We add the defined name to the list in sorted order. */
-    list_defined_name = TAILQ_FIRST(self->defined_names);
-
-    if (list_defined_name == NULL ||
-        _compare_defined_names(defined_name, list_defined_name) < 1) {
-        /* List is empty or defined name goes to the head. */
-        TAILQ_INSERT_HEAD(self->defined_names, defined_name, list_pointers);
-        return LXW_NO_ERROR;
-    }
-
-    TAILQ_FOREACH(list_defined_name, self->defined_names, list_pointers) {
-        int res = _compare_defined_names(defined_name, list_defined_name);
-
-        /* The entry already exists. We exit and don't overwrite. */
-        if (res == 0)
-            goto mem_error;
-
-        /* New defined name is inserted in sorted order before other entries. */
-        if (res < 0) {
-            TAILQ_INSERT_BEFORE(list_defined_name, defined_name,
-                                list_pointers);
-            return LXW_NO_ERROR;
-        }
-    }
-
-    /* If the entry wasn't less than any of the entries in the list we add it
-     * to the end. */
-    TAILQ_INSERT_TAIL(self->defined_names, defined_name, list_pointers);
-    return LXW_NO_ERROR;
-
-mem_error:
-    free(defined_name);
-    return LXW_ERROR_MEMORY_MALLOC_FAILED;
-}
-
-/*
- * Populate the data cache of a chart data series by reading the data from the
- * relevant worksheet and adding it to the cached in the range object as a
- * list of points.
- *
- * Note, the data cache isn't strictly required by Excel but it helps if the
- * chart is embedded in another application such as PowerPoint and it also
- * helps with comparison testing.
- */
-STATIC void
-_populate_range_data_cache(lxw_workbook *self, lxw_series_range *range)
-{
-    lxw_worksheet *worksheet;
-    lxw_row_t row_num;
-    lxw_col_t col_num;
-    lxw_row *row_obj;
-    lxw_cell *cell_obj;
-    struct lxw_series_data_point *data_point;
-    uint16_t num_data_points = 0;
-
-    /* If ignore_cache is set then don't try to populate the cache. This flag
-     * may be set manually, for testing, or due to a case where the cache
-     * can't be calculated.
-     */
-    if (range->ignore_cache)
-        return;
-
-    /* Currently we only handle 2D ranges so ensure either the rows or cols
-     * are the same.
-     */
-    if (range->first_row != range->last_row
-        && range->first_col != range->last_col) {
-        range->ignore_cache = LXW_TRUE;
-        return;
-    }
-
-    /* Check that the sheetname exists. */
-    worksheet = workbook_get_worksheet_by_name(self, range->sheetname);
-    if (!worksheet) {
-        LXW_WARN_FORMAT2("workbook_add_chart(): worksheet name '%s' "
-                         "in chart formula '%s' doesn't exist.",
-                         range->sheetname, range->formula);
-        range->ignore_cache = LXW_TRUE;
-        return;
-    }
-
-    /* We can't read the data when worksheet optimization is on. */
-    if (worksheet->optimize) {
-        range->ignore_cache = LXW_TRUE;
-        return;
-    }
-
-    /* Iterate through the worksheet data and populate the range cache. */
-    for (row_num = range->first_row; row_num <= range->last_row; row_num++) {
-        row_obj = lxw_worksheet_find_row(worksheet, row_num);
-
-        for (col_num = range->first_col; col_num <= range->last_col;
-             col_num++) {
-
-            data_point = calloc(1, sizeof(struct lxw_series_data_point));
-            if (!data_point) {
-                range->ignore_cache = LXW_TRUE;
-                return;
-            }
-
-            cell_obj = lxw_worksheet_find_cell(row_obj, col_num);
-
-            if (cell_obj) {
-                if (cell_obj->type == NUMBER_CELL) {
-                    data_point->number = cell_obj->u.number;
-                }
-
-                if (cell_obj->type == STRING_CELL) {
-                    data_point->string = lxw_strdup(cell_obj->sst_string);
-                    data_point->is_string = LXW_TRUE;
-                    range->has_string_cache = LXW_TRUE;
-                }
-            }
-            else {
-                data_point->no_data = LXW_TRUE;
-            }
-
-            STAILQ_INSERT_TAIL(range->data_cache, data_point, list_pointers);
-            num_data_points++;
-        }
-    }
-
-    range->num_data_points = num_data_points;
-
-}
-
-/* Convert a chart range such as Sheet1!$A$1:$A$5 to a sheet name and row-col
- * dimensions, or vice-versa. This gives us the dimensions to read data back
- * from the worksheet.
- */
-STATIC void
-_populate_range_dimensions(lxw_workbook *self, lxw_series_range *range)
-{
-
-    char formula[LXW_MAX_FORMULA_RANGE_LENGTH] = { 0 };
-    char *tmp_str;
-    char *sheetname;
-
-    /* If neither the range formula or sheetname is defined then this probably
-     * isn't a valid range.
-     */
-    if (!range->formula && !range->sheetname) {
-        range->ignore_cache = LXW_TRUE;
-        return;
-    }
-
-    /* If the sheetname is already defined it was already set via
-     * chart_series_set_categories() or  chart_series_set_values().
-     */
-    if (range->sheetname)
-        return;
-
-    /* Ignore non-contiguous range like (Sheet1!$A$1:$A$2,Sheet1!$A$4:$A$5) */
-    if (range->formula[0] == '(') {
-        range->ignore_cache = LXW_TRUE;
-        return;
-    }
-
-    /* Create a copy of the formula to modify and parse into parts. */
-    lxw_snprintf(formula, LXW_MAX_FORMULA_RANGE_LENGTH, "%s", range->formula);
-
-    /* Check for valid formula. TODO. This needs stronger validation. */
-    tmp_str = strchr(formula, '!');
-
-    if (tmp_str == NULL) {
-        range->ignore_cache = LXW_TRUE;
-        return;
-    }
-    else {
-        /* Split the formulas into sheetname and row-col data. */
-        *tmp_str = '\0';
-        tmp_str++;
-        sheetname = formula;
-
-        /* Remove any worksheet quoting. */
-        if (sheetname[0] == '\'')
-            sheetname++;
-        if (sheetname[strlen(sheetname) - 1] == '\'')
-            sheetname[strlen(sheetname) - 1] = '\0';
-
-        /* Check that the sheetname exists. */
-        if (!workbook_get_worksheet_by_name(self, sheetname)) {
-            LXW_WARN_FORMAT2("workbook_add_chart(): worksheet name '%s' "
-                             "in chart formula '%s' doesn't exist.",
-                             sheetname, range->formula);
-            range->ignore_cache = LXW_TRUE;
-            return;
-        }
-
-        range->sheetname = lxw_strdup(sheetname);
-        range->first_row = lxw_name_to_row(tmp_str);
-        range->first_col = lxw_name_to_col(tmp_str);
-
-        if (strchr(tmp_str, ':')) {
-            /* 2D range. */
-            range->last_row = lxw_name_to_row_2(tmp_str);
-            range->last_col = lxw_name_to_col_2(tmp_str);
-        }
-        else {
-            /* 1D range. */
-            range->last_row = range->first_row;
-            range->last_col = range->first_col;
-        }
-
-    }
-}
-
-/* Set the range dimensions and set the data cache.
- */
-STATIC void
-_populate_range(lxw_workbook *self, lxw_series_range *range)
-{
-    _populate_range_dimensions(self, range);
-    _populate_range_data_cache(self, range);
-}
-
-/*
- * Add "cached" data to charts to provide the numCache and strCache data for
- * series and title/axis ranges.
- */
-STATIC void
-_add_chart_cache_data(lxw_workbook *self)
-{
-    lxw_chart *chart;
-    lxw_chart_series *series;
-
-    STAILQ_FOREACH(chart, self->ordered_charts, ordered_list_pointers) {
-
-        _populate_range(self, chart->title.range);
-        _populate_range(self, chart->x_axis->title.range);
-        _populate_range(self, chart->y_axis->title.range);
-
-        if (STAILQ_EMPTY(chart->series_list))
-            continue;
-
-        STAILQ_FOREACH(series, chart->series_list, list_pointers) {
-            _populate_range(self, series->categories);
-            _populate_range(self, series->values);
-            _populate_range(self, series->title.range);
-        }
-    }
-}
-
-/*
- * Iterate through the worksheets and set up any chart or image drawings.
- */
-STATIC void
-_prepare_drawings(lxw_workbook *self)
-{
-    lxw_worksheet *worksheet;
-    lxw_image_options *image_options;
-    uint16_t chart_ref_id = 0;
-    uint16_t image_ref_id = 0;
-    uint16_t drawing_id = 0;
-
-    STAILQ_FOREACH(worksheet, self->worksheets, list_pointers) {
-
-        if (STAILQ_EMPTY(worksheet->image_data)
-            && STAILQ_EMPTY(worksheet->chart_data))
-            continue;
-
-        drawing_id++;
-
-        STAILQ_FOREACH(image_options, worksheet->chart_data, list_pointers) {
-            chart_ref_id++;
-            lxw_worksheet_prepare_chart(worksheet, chart_ref_id, drawing_id,
-                                        image_options);
-            if (image_options->chart)
-                STAILQ_INSERT_TAIL(self->ordered_charts, image_options->chart,
-                                   ordered_list_pointers);
-        }
-
-        STAILQ_FOREACH(image_options, worksheet->image_data, list_pointers) {
-
-            if (image_options->image_type == LXW_IMAGE_PNG)
-                self->has_png = LXW_TRUE;
-
-            if (image_options->image_type == LXW_IMAGE_JPEG)
-                self->has_jpeg = LXW_TRUE;
-
-            if (image_options->image_type == LXW_IMAGE_BMP)
-                self->has_bmp = LXW_TRUE;
-
-            image_ref_id++;
-
-            lxw_worksheet_prepare_image(worksheet, image_ref_id, drawing_id,
-                                        image_options);
-        }
-    }
-
-    self->drawing_count = drawing_id;
-}
-
-/*
- * Iterate through the worksheets and store any defined names used for print
- * ranges or repeat rows/columns.
- */
-STATIC void
-_prepare_defined_names(lxw_workbook *self)
-{
-    lxw_worksheet *worksheet;
-    char app_name[LXW_DEFINED_NAME_LENGTH];
-    char range[LXW_DEFINED_NAME_LENGTH];
-    char area[LXW_MAX_CELL_RANGE_LENGTH];
-    char first_col[8];
-    char last_col[8];
-
-    STAILQ_FOREACH(worksheet, self->worksheets, list_pointers) {
-
-        /*
-         * Check for autofilter settings and store them.
-         */
-        if (worksheet->autofilter.in_use) {
-
-            lxw_snprintf(app_name, LXW_DEFINED_NAME_LENGTH,
-                         "%s!_FilterDatabase", worksheet->quoted_name);
-
-            lxw_rowcol_to_range_abs(area,
-                                    worksheet->autofilter.first_row,
-                                    worksheet->autofilter.first_col,
-                                    worksheet->autofilter.last_row,
-                                    worksheet->autofilter.last_col);
-
-            lxw_snprintf(range, LXW_DEFINED_NAME_LENGTH, "%s!%s",
-                         worksheet->quoted_name, area);
-
-            /* Autofilters are the only defined name to set the hidden flag. */
-            _store_defined_name(self, "_xlnm._FilterDatabase", app_name,
-                                range, worksheet->index, LXW_TRUE);
-        }
-
-        /*
-         * Check for Print Area settings and store them.
-         */
-        if (worksheet->print_area.in_use) {
-
-            lxw_snprintf(app_name, LXW_DEFINED_NAME_LENGTH,
-                         "%s!Print_Area", worksheet->quoted_name);
-
-            /* Check for print area that is the max row range. */
-            if (worksheet->print_area.first_row == 0
-                && worksheet->print_area.last_row == LXW_ROW_MAX - 1) {
-
-                lxw_col_to_name(first_col,
-                                worksheet->print_area.first_col, LXW_FALSE);
-
-                lxw_col_to_name(last_col,
-                                worksheet->print_area.last_col, LXW_FALSE);
-
-                lxw_snprintf(area, LXW_MAX_CELL_RANGE_LENGTH - 1, "$%s:$%s",
-                             first_col, last_col);
-
-            }
-            /* Check for print area that is the max column range. */
-            else if (worksheet->print_area.first_col == 0
-                     && worksheet->print_area.last_col == LXW_COL_MAX - 1) {
-
-                lxw_snprintf(area, LXW_MAX_CELL_RANGE_LENGTH - 1, "$%d:$%d",
-                             worksheet->print_area.first_row + 1,
-                             worksheet->print_area.last_row + 1);
-
-            }
-            else {
-                lxw_rowcol_to_range_abs(area,
-                                        worksheet->print_area.first_row,
-                                        worksheet->print_area.first_col,
-                                        worksheet->print_area.last_row,
-                                        worksheet->print_area.last_col);
-            }
-
-            lxw_snprintf(range, LXW_DEFINED_NAME_LENGTH, "%s!%s",
-                         worksheet->quoted_name, area);
-
-            _store_defined_name(self, "_xlnm.Print_Area", app_name,
-                                range, worksheet->index, LXW_FALSE);
-        }
-
-        /*
-         * Check for repeat rows/cols. aka, Print Titles and store them.
-         */
-        if (worksheet->repeat_rows.in_use || worksheet->repeat_cols.in_use) {
-            if (worksheet->repeat_rows.in_use
-                && worksheet->repeat_cols.in_use) {
-                lxw_snprintf(app_name, LXW_DEFINED_NAME_LENGTH,
-                             "%s!Print_Titles", worksheet->quoted_name);
-
-                lxw_col_to_name(first_col,
-                                worksheet->repeat_cols.first_col, LXW_FALSE);
-
-                lxw_col_to_name(last_col,
-                                worksheet->repeat_cols.last_col, LXW_FALSE);
-
-                lxw_snprintf(range, LXW_DEFINED_NAME_LENGTH,
-                             "%s!$%s:$%s,%s!$%d:$%d",
-                             worksheet->quoted_name, first_col,
-                             last_col, worksheet->quoted_name,
-                             worksheet->repeat_rows.first_row + 1,
-                             worksheet->repeat_rows.last_row + 1);
-
-                _store_defined_name(self, "_xlnm.Print_Titles", app_name,
-                                    range, worksheet->index, LXW_FALSE);
-            }
-            else if (worksheet->repeat_rows.in_use) {
-
-                lxw_snprintf(app_name, LXW_DEFINED_NAME_LENGTH,
-                             "%s!Print_Titles", worksheet->quoted_name);
-
-                lxw_snprintf(range, LXW_DEFINED_NAME_LENGTH,
-                             "%s!$%d:$%d", worksheet->quoted_name,
-                             worksheet->repeat_rows.first_row + 1,
-                             worksheet->repeat_rows.last_row + 1);
-
-                _store_defined_name(self, "_xlnm.Print_Titles", app_name,
-                                    range, worksheet->index, LXW_FALSE);
-            }
-            else if (worksheet->repeat_cols.in_use) {
-                lxw_snprintf(app_name, LXW_DEFINED_NAME_LENGTH,
-                             "%s!Print_Titles", worksheet->quoted_name);
-
-                lxw_col_to_name(first_col,
-                                worksheet->repeat_cols.first_col, LXW_FALSE);
-
-                lxw_col_to_name(last_col,
-                                worksheet->repeat_cols.last_col, LXW_FALSE);
-
-                lxw_snprintf(range, LXW_DEFINED_NAME_LENGTH,
-                             "%s!$%s:$%s", worksheet->quoted_name,
-                             first_col, last_col);
-
-                _store_defined_name(self, "_xlnm.Print_Titles", app_name,
-                                    range, worksheet->index, LXW_FALSE);
-            }
-        }
-    }
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-
-/*
- * Write the XML declaration.
- */
-STATIC void
-_workbook_xml_declaration(lxw_workbook *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <workbook> element.
- */
-STATIC void
-_write_workbook(lxw_workbook *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns[] = "http://schemas.openxmlformats.org"
-        "/spreadsheetml/2006/main";
-    char xmlns_r[] = "http://schemas.openxmlformats.org"
-        "/officeDocument/2006/relationships";
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
-
-    lxw_xml_start_tag(self->file, "workbook", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <fileVersion> element.
- */
-STATIC void
-_write_file_version(lxw_workbook *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("appName", "xl");
-    LXW_PUSH_ATTRIBUTES_STR("lastEdited", "4");
-    LXW_PUSH_ATTRIBUTES_STR("lowestEdited", "4");
-    LXW_PUSH_ATTRIBUTES_STR("rupBuild", "4505");
-
-    lxw_xml_empty_tag(self->file, "fileVersion", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <workbookPr> element.
- */
-STATIC void
-_write_workbook_pr(lxw_workbook *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("defaultThemeVersion", "124226");
-
-    lxw_xml_empty_tag(self->file, "workbookPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <workbookView> element.
- */
-STATIC void
-_write_workbook_view(lxw_workbook *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xWindow", "240");
-    LXW_PUSH_ATTRIBUTES_STR("yWindow", "15");
-    LXW_PUSH_ATTRIBUTES_STR("windowWidth", "16095");
-    LXW_PUSH_ATTRIBUTES_STR("windowHeight", "9660");
-
-    if (self->first_sheet)
-        LXW_PUSH_ATTRIBUTES_INT("firstSheet", self->first_sheet);
-
-    if (self->active_sheet)
-        LXW_PUSH_ATTRIBUTES_INT("activeTab", self->active_sheet);
-
-    lxw_xml_empty_tag(self->file, "workbookView", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <bookViews> element.
- */
-STATIC void
-_write_book_views(lxw_workbook *self)
-{
-    lxw_xml_start_tag(self->file, "bookViews", NULL);
-
-    _write_workbook_view(self);
-
-    lxw_xml_end_tag(self->file, "bookViews");
-}
-
-/*
- * Write the <sheet> element.
- */
-STATIC void
-_write_sheet(lxw_workbook *self, const char *name, uint32_t sheet_id,
-             uint8_t hidden)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char r_id[LXW_MAX_ATTRIBUTE_LENGTH] = "rId1";
-
-    lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", sheet_id);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("name", name);
-    LXW_PUSH_ATTRIBUTES_INT("sheetId", sheet_id);
-
-    if (hidden)
-        LXW_PUSH_ATTRIBUTES_STR("state", "hidden");
-
-    LXW_PUSH_ATTRIBUTES_STR("r:id", r_id);
-
-    lxw_xml_empty_tag(self->file, "sheet", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <sheets> element.
- */
-STATIC void
-_write_sheets(lxw_workbook *self)
-{
-    lxw_worksheet *worksheet;
-
-    lxw_xml_start_tag(self->file, "sheets", NULL);
-
-    STAILQ_FOREACH(worksheet, self->worksheets, list_pointers) {
-        _write_sheet(self, worksheet->name, worksheet->index + 1,
-                     worksheet->hidden);
-    }
-
-    lxw_xml_end_tag(self->file, "sheets");
-}
-
-/*
- * Write the <calcPr> element.
- */
-STATIC void
-_write_calc_pr(lxw_workbook *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("calcId", "124519");
-    LXW_PUSH_ATTRIBUTES_STR("fullCalcOnLoad", "1");
-
-    lxw_xml_empty_tag(self->file, "calcPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <definedName> element.
- */
-STATIC void
-_write_defined_name(lxw_workbook *self, lxw_defined_name *defined_name)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("name", defined_name->name);
-
-    if (defined_name->index != -1)
-        LXW_PUSH_ATTRIBUTES_INT("localSheetId", defined_name->index);
-
-    if (defined_name->hidden)
-        LXW_PUSH_ATTRIBUTES_INT("hidden", 1);
-
-    lxw_xml_data_element(self->file, "definedName", defined_name->formula,
-                         &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <definedNames> element.
- */
-STATIC void
-_write_defined_names(lxw_workbook *self)
-{
-    lxw_defined_name *defined_name;
-
-    if (TAILQ_EMPTY(self->defined_names))
-        return;
-
-    lxw_xml_start_tag(self->file, "definedNames", NULL);
-
-    TAILQ_FOREACH(defined_name, self->defined_names, list_pointers) {
-        _write_defined_name(self, defined_name);
-    }
-
-    lxw_xml_end_tag(self->file, "definedNames");
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_workbook_assemble_xml_file(lxw_workbook *self)
-{
-    /* Prepare workbook and sub-objects for writing. */
-    _prepare_workbook(self);
-
-    /* Write the XML declaration. */
-    _workbook_xml_declaration(self);
-
-    /* Write the root workbook element. */
-    _write_workbook(self);
-
-    /* Write the XLSX file version. */
-    _write_file_version(self);
-
-    /* Write the workbook properties. */
-    _write_workbook_pr(self);
-
-    /* Write the workbook view properties. */
-    _write_book_views(self);
-
-    /* Write the worksheet names and ids. */
-    _write_sheets(self);
-
-    /* Write the workbook defined names. */
-    _write_defined_names(self);
-
-    /* Write the workbook calculation properties. */
-    _write_calc_pr(self);
-
-    /* Close the workbook tag. */
-    lxw_xml_end_tag(self->file, "workbook");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new workbook object.
- */
-lxw_workbook *
-workbook_new(const char *filename)
-{
-    return workbook_new_opt(filename, NULL);
-}
-
-/* Deprecated function name for backwards compatibility. */
-lxw_workbook *
-new_workbook(const char *filename)
-{
-    return workbook_new_opt(filename, NULL);
-}
-
-/* Deprecated function name for backwards compatibility. */
-lxw_workbook *
-new_workbook_opt(const char *filename, lxw_workbook_options *options)
-{
-    return workbook_new_opt(filename, options);
-}
-
-/*
- * Create a new workbook object with options.
- */
-lxw_workbook *
-workbook_new_opt(const char *filename, lxw_workbook_options *options)
-{
-    lxw_format *format;
-    lxw_workbook *workbook;
-
-    /* Create the workbook object. */
-    workbook = calloc(1, sizeof(lxw_workbook));
-    GOTO_LABEL_ON_MEM_ERROR(workbook, mem_error);
-    workbook->filename = lxw_strdup(filename);
-
-    /* Add the worksheets list. */
-    workbook->worksheets = calloc(1, sizeof(struct lxw_worksheets));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->worksheets, mem_error);
-    STAILQ_INIT(workbook->worksheets);
-
-    /* Add the worksheet names tree. */
-    workbook->worksheet_names = calloc(1, sizeof(struct lxw_worksheet_names));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->worksheet_names, mem_error);
-    RB_INIT(workbook->worksheet_names);
-
-    /* Add the charts list. */
-    workbook->charts = calloc(1, sizeof(struct lxw_charts));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->charts, mem_error);
-    STAILQ_INIT(workbook->charts);
-
-    /* Add the ordered charts list to track chart insertion order. */
-    workbook->ordered_charts = calloc(1, sizeof(struct lxw_charts));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->ordered_charts, mem_error);
-    STAILQ_INIT(workbook->ordered_charts);
-
-    /* Add the formats list. */
-    workbook->formats = calloc(1, sizeof(struct lxw_formats));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->formats, mem_error);
-    STAILQ_INIT(workbook->formats);
-
-    /* Add the defined_names list. */
-    workbook->defined_names = calloc(1, sizeof(struct lxw_defined_names));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->defined_names, mem_error);
-    TAILQ_INIT(workbook->defined_names);
-
-    /* Add the shared strings table. */
-    workbook->sst = lxw_sst_new();
-    GOTO_LABEL_ON_MEM_ERROR(workbook->sst, mem_error);
-
-    /* Add the default workbook properties. */
-    workbook->properties = calloc(1, sizeof(lxw_doc_properties));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->properties, mem_error);
-
-    /* Add a hash table to track format indices. */
-    workbook->used_xf_formats = lxw_hash_new(128, 1, 0);
-    GOTO_LABEL_ON_MEM_ERROR(workbook->used_xf_formats, mem_error);
-
-    /* Add the worksheets list. */
-    workbook->custom_properties =
-        calloc(1, sizeof(struct lxw_custom_properties));
-    GOTO_LABEL_ON_MEM_ERROR(workbook->custom_properties, mem_error);
-    STAILQ_INIT(workbook->custom_properties);
-
-    /* Add the default cell format. */
-    format = workbook_add_format(workbook);
-    GOTO_LABEL_ON_MEM_ERROR(format, mem_error);
-
-    /* Initialize its index. */
-    lxw_format_get_xf_index(format);
-
-    if (options) {
-        workbook->options.constant_memory = options->constant_memory;
-        workbook->options.tmpdir = lxw_strdup(options->tmpdir);
-    }
-
-    return workbook;
-
-mem_error:
-    lxw_workbook_free(workbook);
-    workbook = NULL;
-    return NULL;
-}
-
-/*
- * Add a new worksheet to the Excel workbook.
- */
-lxw_worksheet *
-workbook_add_worksheet(lxw_workbook *self, const char *sheetname)
-{
-    lxw_worksheet *worksheet;
-    lxw_worksheet_name *worksheet_name = NULL;
-    lxw_error error;
-    lxw_worksheet_init_data init_data = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    char *new_name = NULL;
-
-    if (sheetname) {
-        /* Use the user supplied name. */
-        init_data.name = lxw_strdup(sheetname);
-        init_data.quoted_name = lxw_quote_sheetname((char *) sheetname);
-    }
-    else {
-        /* Use the default SheetN name. */
-        new_name = malloc(LXW_MAX_SHEETNAME_LENGTH);
-        GOTO_LABEL_ON_MEM_ERROR(new_name, mem_error);
-
-        lxw_snprintf(new_name, LXW_MAX_SHEETNAME_LENGTH, "Sheet%d",
-                     self->num_sheets + 1);
-        init_data.name = new_name;
-        init_data.quoted_name = lxw_strdup(new_name);
-    }
-
-    /* Check that the worksheet name is valid. */
-    error = workbook_validate_worksheet_name(self, init_data.name);
-    if (error) {
-        LXW_WARN_FORMAT2("workbook_add_worksheet(): worksheet name '%s' has "
-                         "error: %s", init_data.name, lxw_strerror(error));
-        goto mem_error;
-    }
-
-    /* Create a struct to find/store the worksheet name/pointer. */
-    worksheet_name = calloc(1, sizeof(struct lxw_worksheet_name));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet_name, mem_error);
-
-    /* Initialize the metadata to pass to the worksheet. */
-    init_data.hidden = 0;
-    init_data.index = self->num_sheets;
-    init_data.sst = self->sst;
-    init_data.optimize = self->options.constant_memory;
-    init_data.active_sheet = &self->active_sheet;
-    init_data.first_sheet = &self->first_sheet;
-    init_data.tmpdir = self->options.tmpdir;
-
-    /* Create a new worksheet object. */
-    worksheet = lxw_worksheet_new(&init_data);
-    GOTO_LABEL_ON_MEM_ERROR(worksheet, mem_error);
-
-    self->num_sheets++;
-    STAILQ_INSERT_TAIL(self->worksheets, worksheet, list_pointers);
-
-    /* Store the worksheet so we can look it up by name. */
-    worksheet_name->name = init_data.name;
-    worksheet_name->worksheet = worksheet;
-    RB_INSERT(lxw_worksheet_names, self->worksheet_names, worksheet_name);
-
-    return worksheet;
-
-mem_error:
-    free(init_data.name);
-    free(init_data.quoted_name);
-    free(worksheet_name);
-    return NULL;
-}
-
-/*
- * Add a new chart to the Excel workbook.
- */
-lxw_chart *
-workbook_add_chart(lxw_workbook *self, uint8_t type)
-{
-    lxw_chart *chart;
-
-    /* Create a new chart object. */
-    chart = lxw_chart_new(type);
-
-    if (chart)
-        STAILQ_INSERT_TAIL(self->charts, chart, list_pointers);
-
-    return chart;
-}
-
-/*
- * Add a new format to the Excel workbook.
- */
-lxw_format *
-workbook_add_format(lxw_workbook *self)
-{
-    /* Create a new format object. */
-    lxw_format *format = lxw_format_new();
-    RETURN_ON_MEM_ERROR(format, NULL);
-
-    format->xf_format_indices = self->used_xf_formats;
-    format->num_xf_formats = &self->num_xf_formats;
-
-    STAILQ_INSERT_TAIL(self->formats, format, list_pointers);
-
-    return format;
-}
-
-/*
- * Call finalization code and close file.
- */
-lxw_error
-workbook_close(lxw_workbook *self)
-{
-    lxw_worksheet *worksheet = NULL;
-    lxw_packager *packager = NULL;
-    lxw_error error = LXW_NO_ERROR;
-
-    /* Add a default worksheet if non have been added. */
-    if (!self->num_sheets)
-        workbook_add_worksheet(self, NULL);
-
-    /* Ensure that at least one worksheet has been selected. */
-    if (self->active_sheet == 0) {
-        worksheet = STAILQ_FIRST(self->worksheets);
-        worksheet->selected = 1;
-        worksheet->hidden = 0;
-    }
-
-    /* Set the active sheet. */
-    STAILQ_FOREACH(worksheet, self->worksheets, list_pointers) {
-        if (worksheet->index == self->active_sheet)
-            worksheet->active = 1;
-    }
-
-    /* Set the defined names for the worksheets such as Print Titles. */
-    _prepare_defined_names(self);
-
-    /* Prepare the drawings, charts and images. */
-    _prepare_drawings(self);
-
-    /* Add cached data to charts. */
-    _add_chart_cache_data(self);
-
-    /* Create a packager object to assemble sub-elements into a zip file. */
-    packager = lxw_packager_new(self->filename, self->options.tmpdir);
-
-    /* If the packager fails it is generally due to a zip permission error. */
-    if (packager == NULL) {
-        fprintf(stderr, "[ERROR] workbook_close(): "
-                "Error creating '%s'. "
-                "Error = %s\n", self->filename, strerror(errno));
-
-        error = LXW_ERROR_CREATING_XLSX_FILE;
-        goto mem_error;
-    }
-
-    /* Set the workbook object in the packager. */
-    packager->workbook = self;
-
-    /* Assemble all the sub-files in the xlsx package. */
-    error = lxw_create_package(packager);
-
-    /* Error and non-error conditions fall through to the cleanup code. */
-    if (error == LXW_ERROR_CREATING_TMPFILE) {
-        fprintf(stderr, "[ERROR] workbook_close(): "
-                "Error creating tmpfile(s) to assemble '%s'. "
-                "Error = %s\n", self->filename, strerror(errno));
-    }
-
-    /* If LXW_ERROR_ZIP_FILE_OPERATION then errno is set by zlib. */
-    if (error == LXW_ERROR_ZIP_FILE_OPERATION) {
-        fprintf(stderr, "[ERROR] workbook_close(): "
-                "Zlib error while creating xlsx file '%s'. "
-                "Error = %s\n", self->filename, strerror(errno));
-    }
-
-    /* The next 2 error conditions don't set errno. */
-    if (error == LXW_ERROR_ZIP_FILE_ADD) {
-        fprintf(stderr, "[ERROR] workbook_close(): "
-                "Zlib error adding file to xlsx file '%s'.\n",
-                self->filename);
-    }
-
-    if (error == LXW_ERROR_ZIP_CLOSE) {
-        fprintf(stderr, "[ERROR] workbook_close(): "
-                "Zlib error closing xlsx file '%s'.\n", self->filename);
-    }
-
-mem_error:
-    lxw_packager_free(packager);
-    lxw_workbook_free(self);
-    return error;
-}
-
-/*
- * Create a defined name in Excel. We handle global/workbook level names and
- * local/worksheet names.
- */
-lxw_error
-workbook_define_name(lxw_workbook *self, const char *name,
-                     const char *formula)
-{
-    return _store_defined_name(self, name, NULL, formula, -1, LXW_FALSE);
-}
-
-/*
- * Set the document properties such as Title, Author etc.
- */
-lxw_error
-workbook_set_properties(lxw_workbook *self, lxw_doc_properties *user_props)
-{
-    lxw_doc_properties *doc_props;
-
-    /* Free any existing properties. */
-    _free_doc_properties(self->properties);
-
-    doc_props = calloc(1, sizeof(lxw_doc_properties));
-    GOTO_LABEL_ON_MEM_ERROR(doc_props, mem_error);
-
-    /* Copy the user properties to an internal structure. */
-    if (user_props->title) {
-        doc_props->title = lxw_strdup(user_props->title);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->title, mem_error);
-    }
-
-    if (user_props->subject) {
-        doc_props->subject = lxw_strdup(user_props->subject);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->subject, mem_error);
-    }
-
-    if (user_props->author) {
-        doc_props->author = lxw_strdup(user_props->author);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->author, mem_error);
-    }
-
-    if (user_props->manager) {
-        doc_props->manager = lxw_strdup(user_props->manager);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->manager, mem_error);
-    }
-
-    if (user_props->company) {
-        doc_props->company = lxw_strdup(user_props->company);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->company, mem_error);
-    }
-
-    if (user_props->category) {
-        doc_props->category = lxw_strdup(user_props->category);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->category, mem_error);
-    }
-
-    if (user_props->keywords) {
-        doc_props->keywords = lxw_strdup(user_props->keywords);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->keywords, mem_error);
-    }
-
-    if (user_props->comments) {
-        doc_props->comments = lxw_strdup(user_props->comments);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->comments, mem_error);
-    }
-
-    if (user_props->status) {
-        doc_props->status = lxw_strdup(user_props->status);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->status, mem_error);
-    }
-
-    if (user_props->hyperlink_base) {
-        doc_props->hyperlink_base = lxw_strdup(user_props->hyperlink_base);
-        GOTO_LABEL_ON_MEM_ERROR(doc_props->hyperlink_base, mem_error);
-    }
-
-    self->properties = doc_props;
-
-    return LXW_NO_ERROR;
-
-mem_error:
-    _free_doc_properties(doc_props);
-    return LXW_ERROR_MEMORY_MALLOC_FAILED;
-}
-
-/*
- * Set a string custom document property.
- */
-lxw_error
-workbook_set_custom_property_string(lxw_workbook *self, const char *name,
-                                    const char *value)
-{
-    lxw_custom_property *custom_property;
-
-    if (!name) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_string(): "
-                        "parameter 'name' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (!value) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_string(): "
-                        "parameter 'value' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (lxw_utf8_strlen(name) > 255) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_string(): parameter "
-                        "'name' exceeds Excel length limit of 255.");
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-    }
-
-    if (lxw_utf8_strlen(value) > 255) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_string(): parameter "
-                        "'value' exceeds Excel length limit of 255.");
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-    }
-
-    /* Create a struct to hold the custom property. */
-    custom_property = calloc(1, sizeof(struct lxw_custom_property));
-    RETURN_ON_MEM_ERROR(custom_property, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    custom_property->name = lxw_strdup(name);
-    custom_property->u.string = lxw_strdup(value);
-    custom_property->type = LXW_CUSTOM_STRING;
-
-    STAILQ_INSERT_TAIL(self->custom_properties, custom_property,
-                       list_pointers);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set a double number custom document property.
- */
-lxw_error
-workbook_set_custom_property_number(lxw_workbook *self, const char *name,
-                                    double value)
-{
-    lxw_custom_property *custom_property;
-
-    if (!name) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_number(): parameter "
-                        "'name' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (lxw_utf8_strlen(name) > 255) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_number(): parameter "
-                        "'name' exceeds Excel length limit of 255.");
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-    }
-
-    /* Create a struct to hold the custom property. */
-    custom_property = calloc(1, sizeof(struct lxw_custom_property));
-    RETURN_ON_MEM_ERROR(custom_property, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    custom_property->name = lxw_strdup(name);
-    custom_property->u.number = value;
-    custom_property->type = LXW_CUSTOM_DOUBLE;
-
-    STAILQ_INSERT_TAIL(self->custom_properties, custom_property,
-                       list_pointers);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set a integer number custom document property.
- */
-lxw_error
-workbook_set_custom_property_integer(lxw_workbook *self, const char *name,
-                                     int32_t value)
-{
-    lxw_custom_property *custom_property;
-
-    if (!name) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_integer(): parameter "
-                        "'name' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (strlen(name) > 255) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_integer(): parameter "
-                        "'name' exceeds Excel length limit of 255.");
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-    }
-
-    /* Create a struct to hold the custom property. */
-    custom_property = calloc(1, sizeof(struct lxw_custom_property));
-    RETURN_ON_MEM_ERROR(custom_property, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    custom_property->name = lxw_strdup(name);
-    custom_property->u.integer = value;
-    custom_property->type = LXW_CUSTOM_INTEGER;
-
-    STAILQ_INSERT_TAIL(self->custom_properties, custom_property,
-                       list_pointers);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set a boolean custom document property.
- */
-lxw_error
-workbook_set_custom_property_boolean(lxw_workbook *self, const char *name,
-                                     uint8_t value)
-{
-    lxw_custom_property *custom_property;
-
-    if (!name) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_boolean(): parameter "
-                        "'name' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (lxw_utf8_strlen(name) > 255) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_boolean(): parameter "
-                        "'name' exceeds Excel length limit of 255.");
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-    }
-
-    /* Create a struct to hold the custom property. */
-    custom_property = calloc(1, sizeof(struct lxw_custom_property));
-    RETURN_ON_MEM_ERROR(custom_property, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    custom_property->name = lxw_strdup(name);
-    custom_property->u.boolean = value;
-    custom_property->type = LXW_CUSTOM_BOOLEAN;
-
-    STAILQ_INSERT_TAIL(self->custom_properties, custom_property,
-                       list_pointers);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set a datetime custom document property.
- */
-lxw_error
-workbook_set_custom_property_datetime(lxw_workbook *self, const char *name,
-                                      lxw_datetime *datetime)
-{
-    lxw_custom_property *custom_property;
-
-    if (!name) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_datetime(): parameter "
-                        "'name' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (lxw_utf8_strlen(name) > 255) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_datetime(): parameter "
-                        "'name' exceeds Excel length limit of 255.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    if (!datetime) {
-        LXW_WARN_FORMAT("workbook_set_custom_property_datetime(): parameter "
-                        "'datetime' cannot be NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    /* Create a struct to hold the custom property. */
-    custom_property = calloc(1, sizeof(struct lxw_custom_property));
-    RETURN_ON_MEM_ERROR(custom_property, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    custom_property->name = lxw_strdup(name);
-
-    memcpy(&custom_property->u.datetime, datetime, sizeof(lxw_datetime));
-    custom_property->type = LXW_CUSTOM_DATETIME;
-
-    STAILQ_INSERT_TAIL(self->custom_properties, custom_property,
-                       list_pointers);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Get a worksheet object from its name.
- */
-lxw_worksheet *
-workbook_get_worksheet_by_name(lxw_workbook *self, const char *name)
-{
-    lxw_worksheet_name worksheet_name;
-    lxw_worksheet_name *found;
-
-    if (!name)
-        return NULL;
-
-    worksheet_name.name = name;
-    found = RB_FIND(lxw_worksheet_names,
-                    self->worksheet_names, &worksheet_name);
-
-    if (found)
-        return found->worksheet;
-    else
-        return NULL;
-}
-
-/*
- * Validate the worksheet name based on Excel's rules.
- */
-lxw_error
-workbook_validate_worksheet_name(lxw_workbook *self, const char *sheetname)
-{
-    /* Check the UTF-8 length of the worksheet name. */
-    if (lxw_utf8_strlen(sheetname) > LXW_SHEETNAME_MAX)
-        return LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED;
-
-    /* Check that the worksheet name doesn't contain invalid characters. */
-    if (strpbrk(sheetname, "[]:*?/\\"))
-        return LXW_ERROR_INVALID_SHEETNAME_CHARACTER;
-
-    /* Check if the worksheet name is already in use. */
-    if (workbook_get_worksheet_by_name(self, sheetname))
-        return LXW_ERROR_SHEETNAME_ALREADY_USED;
-
-    return LXW_NO_ERROR;
-}

+ 0 - 5739
library/src/worksheet.c

@@ -1,5739 +0,0 @@
-/*****************************************************************************
- * worksheet - A library for creating Excel XLSX worksheet files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include <ctype.h>
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/worksheet.h"
-#include "xlsxwriter/format.h"
-#include "xlsxwriter/utility.h"
-#include "xlsxwriter/relationships.h"
-
-#define LXW_STR_MAX                      32767
-#define LXW_BUFFER_SIZE                  4096
-#define LXW_PORTRAIT                     1
-#define LXW_LANDSCAPE                    0
-#define LXW_PRINT_ACROSS                 1
-#define LXW_VALIDATION_MAX_TITLE_LENGTH  32
-#define LXW_VALIDATION_MAX_STRING_LENGTH 255
-
-/*
- * Forward declarations.
- */
-STATIC void _worksheet_write_rows(lxw_worksheet *self);
-STATIC int _row_cmp(lxw_row *row1, lxw_row *row2);
-STATIC int _cell_cmp(lxw_cell *cell1, lxw_cell *cell2);
-
-#ifndef __clang_analyzer__
-LXW_RB_GENERATE_ROW(lxw_table_rows, lxw_row, tree_pointers, _row_cmp);
-LXW_RB_GENERATE_CELL(lxw_table_cells, lxw_cell, tree_pointers, _cell_cmp);
-#endif
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Find but don't create a row object for a given row number.
- */
-lxw_row *
-lxw_worksheet_find_row(lxw_worksheet *self, lxw_row_t row_num)
-{
-    lxw_row row;
-
-    row.row_num = row_num;
-
-    return RB_FIND(lxw_table_rows, self->table, &row);
-}
-
-/*
- * Find but don't create a cell object for a given row object and col number.
- */
-lxw_cell *
-lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num)
-{
-    lxw_cell cell;
-
-    if (!row)
-        return NULL;
-
-    cell.col_num = col_num;
-
-    return RB_FIND(lxw_table_cells, row->cells, &cell);
-}
-
-/*
- * Create a new worksheet object.
- */
-lxw_worksheet *
-lxw_worksheet_new(lxw_worksheet_init_data *init_data)
-{
-    lxw_worksheet *worksheet = calloc(1, sizeof(lxw_worksheet));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet, mem_error);
-
-    worksheet->table = calloc(1, sizeof(struct lxw_table_rows));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->table, mem_error);
-    RB_INIT(worksheet->table);
-
-    worksheet->hyperlinks = calloc(1, sizeof(struct lxw_table_rows));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->hyperlinks, mem_error);
-    RB_INIT(worksheet->hyperlinks);
-
-    /* Initialize the cached rows. */
-    worksheet->table->cached_row_num = LXW_ROW_MAX + 1;
-    worksheet->hyperlinks->cached_row_num = LXW_ROW_MAX + 1;
-
-    if (init_data && init_data->optimize) {
-        worksheet->array = calloc(LXW_COL_MAX, sizeof(struct lxw_cell *));
-        GOTO_LABEL_ON_MEM_ERROR(worksheet->array, mem_error);
-    }
-
-    worksheet->col_options =
-        calloc(LXW_COL_META_MAX, sizeof(lxw_col_options *));
-    worksheet->col_options_max = LXW_COL_META_MAX;
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->col_options, mem_error);
-
-    worksheet->col_formats = calloc(LXW_COL_META_MAX, sizeof(lxw_format *));
-    worksheet->col_formats_max = LXW_COL_META_MAX;
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->col_formats, mem_error);
-
-    worksheet->optimize_row = calloc(1, sizeof(struct lxw_row));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->optimize_row, mem_error);
-    worksheet->optimize_row->height = LXW_DEF_ROW_HEIGHT;
-
-    worksheet->merged_ranges = calloc(1, sizeof(struct lxw_merged_ranges));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->merged_ranges, mem_error);
-    STAILQ_INIT(worksheet->merged_ranges);
-
-    worksheet->image_data = calloc(1, sizeof(struct lxw_image_data));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->image_data, mem_error);
-    STAILQ_INIT(worksheet->image_data);
-
-    worksheet->chart_data = calloc(1, sizeof(struct lxw_chart_data));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->chart_data, mem_error);
-    STAILQ_INIT(worksheet->chart_data);
-
-    worksheet->selections = calloc(1, sizeof(struct lxw_selections));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->selections, mem_error);
-    STAILQ_INIT(worksheet->selections);
-
-    worksheet->data_validations =
-        calloc(1, sizeof(struct lxw_data_validations));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->data_validations, mem_error);
-    STAILQ_INIT(worksheet->data_validations);
-
-    worksheet->external_hyperlinks = calloc(1, sizeof(struct lxw_rel_tuples));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->external_hyperlinks, mem_error);
-    STAILQ_INIT(worksheet->external_hyperlinks);
-
-    worksheet->external_drawing_links =
-        calloc(1, sizeof(struct lxw_rel_tuples));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->external_drawing_links, mem_error);
-    STAILQ_INIT(worksheet->external_drawing_links);
-
-    worksheet->drawing_links = calloc(1, sizeof(struct lxw_rel_tuples));
-    GOTO_LABEL_ON_MEM_ERROR(worksheet->drawing_links, mem_error);
-    STAILQ_INIT(worksheet->drawing_links);
-
-    if (init_data && init_data->optimize) {
-        FILE *tmpfile;
-
-        tmpfile = lxw_tmpfile(init_data->tmpdir);
-        if (!tmpfile) {
-            LXW_ERROR("Error creating tmpfile() for worksheet in "
-                      "'constant_memory' mode.");
-            goto mem_error;
-        }
-
-        worksheet->optimize_tmpfile = tmpfile;
-        GOTO_LABEL_ON_MEM_ERROR(worksheet->optimize_tmpfile, mem_error);
-        worksheet->file = worksheet->optimize_tmpfile;
-    }
-
-    /* Initialize the worksheet dimensions. */
-    worksheet->dim_rowmax = 0;
-    worksheet->dim_colmax = 0;
-    worksheet->dim_rowmin = LXW_ROW_MAX;
-    worksheet->dim_colmin = LXW_COL_MAX;
-
-    worksheet->default_row_height = LXW_DEF_ROW_HEIGHT;
-    worksheet->default_row_pixels = 20;
-    worksheet->default_col_pixels = 64;
-
-    /* Initialize the page setup properties. */
-    worksheet->fit_height = 0;
-    worksheet->fit_width = 0;
-    worksheet->page_start = 0;
-    worksheet->print_scale = 100;
-    worksheet->fit_page = 0;
-    worksheet->orientation = LXW_TRUE;
-    worksheet->page_order = 0;
-    worksheet->page_setup_changed = LXW_FALSE;
-    worksheet->page_view = LXW_FALSE;
-    worksheet->paper_size = 0;
-    worksheet->vertical_dpi = 0;
-    worksheet->horizontal_dpi = 0;
-    worksheet->margin_left = 0.7;
-    worksheet->margin_right = 0.7;
-    worksheet->margin_top = 0.75;
-    worksheet->margin_bottom = 0.75;
-    worksheet->margin_header = 0.3;
-    worksheet->margin_footer = 0.3;
-    worksheet->print_gridlines = 0;
-    worksheet->screen_gridlines = 1;
-    worksheet->print_options_changed = 0;
-    worksheet->zoom = 100;
-    worksheet->zoom_scale_normal = LXW_TRUE;
-    worksheet->show_zeros = LXW_TRUE;
-    worksheet->outline_on = LXW_TRUE;
-    worksheet->outline_style = LXW_TRUE;
-    worksheet->outline_below = LXW_TRUE;
-    worksheet->outline_right = LXW_FALSE;
-    worksheet->tab_color = LXW_COLOR_UNSET;
-
-    if (init_data) {
-        worksheet->name = init_data->name;
-        worksheet->quoted_name = init_data->quoted_name;
-        worksheet->tmpdir = init_data->tmpdir;
-        worksheet->index = init_data->index;
-        worksheet->hidden = init_data->hidden;
-        worksheet->sst = init_data->sst;
-        worksheet->optimize = init_data->optimize;
-        worksheet->active_sheet = init_data->active_sheet;
-        worksheet->first_sheet = init_data->first_sheet;
-    }
-
-    return worksheet;
-
-mem_error:
-    lxw_worksheet_free(worksheet);
-    return NULL;
-}
-
-/*
- * Free a worksheet cell.
- */
-STATIC void
-_free_cell(lxw_cell *cell)
-{
-    if (!cell)
-        return;
-
-    if (cell->type != NUMBER_CELL && cell->type != STRING_CELL
-        && cell->type != BLANK_CELL && cell->type != BOOLEAN_CELL) {
-
-        free(cell->u.string);
-    }
-
-    free(cell->user_data1);
-    free(cell->user_data2);
-
-    free(cell);
-}
-
-/*
- * Free a worksheet row.
- */
-STATIC void
-_free_row(lxw_row *row)
-{
-    lxw_cell *cell;
-    lxw_cell *next_cell;
-
-    if (!row)
-        return;
-
-    for (cell = RB_MIN(lxw_table_cells, row->cells); cell; cell = next_cell) {
-        next_cell = RB_NEXT(lxw_table_cells, row->cells, cell);
-        RB_REMOVE(lxw_table_cells, row->cells, cell);
-        _free_cell(cell);
-    }
-
-    free(row->cells);
-    free(row);
-}
-
-/*
- * Free a worksheet image_options.
- */
-STATIC void
-_free_image_options(lxw_image_options *image)
-{
-    if (!image)
-        return;
-
-    free(image->filename);
-    free(image->short_name);
-    free(image->extension);
-    free(image->url);
-    free(image->tip);
-    free(image);
-}
-
-/*
- * Free a worksheet data_validation.
- */
-STATIC void
-_free_data_validation(lxw_data_validation *data_validation)
-{
-    if (!data_validation)
-        return;
-
-    free(data_validation->value_formula);
-    free(data_validation->maximum_formula);
-    free(data_validation->input_title);
-    free(data_validation->input_message);
-    free(data_validation->error_title);
-    free(data_validation->error_message);
-    free(data_validation->minimum_formula);
-
-    free(data_validation);
-}
-
-/*
- * Free a worksheet object.
- */
-void
-lxw_worksheet_free(lxw_worksheet *worksheet)
-{
-    lxw_row *row;
-    lxw_row *next_row;
-    lxw_col_t col;
-    lxw_merged_range *merged_range;
-    lxw_image_options *image_options;
-    lxw_selection *selection;
-    lxw_data_validation *data_validation;
-    lxw_rel_tuple *relationship;
-
-    if (!worksheet)
-        return;
-
-    if (worksheet->col_options) {
-        for (col = 0; col < worksheet->col_options_max; col++) {
-            if (worksheet->col_options[col])
-                free(worksheet->col_options[col]);
-        }
-    }
-
-    free(worksheet->col_options);
-    free(worksheet->col_sizes);
-    free(worksheet->col_formats);
-
-    if (worksheet->table) {
-        for (row = RB_MIN(lxw_table_rows, worksheet->table); row;
-             row = next_row) {
-
-            next_row = RB_NEXT(lxw_table_rows, worksheet->table, row);
-            RB_REMOVE(lxw_table_rows, worksheet->table, row);
-            _free_row(row);
-        }
-
-        free(worksheet->table);
-    }
-
-    if (worksheet->hyperlinks) {
-        for (row = RB_MIN(lxw_table_rows, worksheet->hyperlinks); row;
-             row = next_row) {
-
-            next_row = RB_NEXT(lxw_table_rows, worksheet->hyperlinks, row);
-            RB_REMOVE(lxw_table_rows, worksheet->hyperlinks, row);
-            _free_row(row);
-        }
-
-        free(worksheet->hyperlinks);
-    }
-
-    if (worksheet->merged_ranges) {
-        while (!STAILQ_EMPTY(worksheet->merged_ranges)) {
-            merged_range = STAILQ_FIRST(worksheet->merged_ranges);
-            STAILQ_REMOVE_HEAD(worksheet->merged_ranges, list_pointers);
-            free(merged_range);
-        }
-
-        free(worksheet->merged_ranges);
-    }
-
-    if (worksheet->image_data) {
-        while (!STAILQ_EMPTY(worksheet->image_data)) {
-            image_options = STAILQ_FIRST(worksheet->image_data);
-            STAILQ_REMOVE_HEAD(worksheet->image_data, list_pointers);
-            _free_image_options(image_options);
-        }
-
-        free(worksheet->image_data);
-    }
-
-    if (worksheet->chart_data) {
-        while (!STAILQ_EMPTY(worksheet->chart_data)) {
-            image_options = STAILQ_FIRST(worksheet->chart_data);
-            STAILQ_REMOVE_HEAD(worksheet->chart_data, list_pointers);
-            _free_image_options(image_options);
-        }
-
-        free(worksheet->chart_data);
-    }
-
-    if (worksheet->selections) {
-        while (!STAILQ_EMPTY(worksheet->selections)) {
-            selection = STAILQ_FIRST(worksheet->selections);
-            STAILQ_REMOVE_HEAD(worksheet->selections, list_pointers);
-            free(selection);
-        }
-
-        free(worksheet->selections);
-    }
-
-    if (worksheet->data_validations) {
-        while (!STAILQ_EMPTY(worksheet->data_validations)) {
-            data_validation = STAILQ_FIRST(worksheet->data_validations);
-            STAILQ_REMOVE_HEAD(worksheet->data_validations, list_pointers);
-            _free_data_validation(data_validation);
-        }
-
-        free(worksheet->data_validations);
-    }
-
-    /* TODO. Add function for freeing the relationship lists. */
-    while (!STAILQ_EMPTY(worksheet->external_hyperlinks)) {
-        relationship = STAILQ_FIRST(worksheet->external_hyperlinks);
-        STAILQ_REMOVE_HEAD(worksheet->external_hyperlinks, list_pointers);
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-    free(worksheet->external_hyperlinks);
-
-    while (!STAILQ_EMPTY(worksheet->external_drawing_links)) {
-        relationship = STAILQ_FIRST(worksheet->external_drawing_links);
-        STAILQ_REMOVE_HEAD(worksheet->external_drawing_links, list_pointers);
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-    free(worksheet->external_drawing_links);
-
-    while (!STAILQ_EMPTY(worksheet->drawing_links)) {
-        relationship = STAILQ_FIRST(worksheet->drawing_links);
-        STAILQ_REMOVE_HEAD(worksheet->drawing_links, list_pointers);
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-    free(worksheet->drawing_links);
-
-    if (worksheet->array) {
-        for (col = 0; col < LXW_COL_MAX; col++) {
-            _free_cell(worksheet->array[col]);
-        }
-        free(worksheet->array);
-    }
-
-    if (worksheet->optimize_row)
-        free(worksheet->optimize_row);
-
-    if (worksheet->drawing)
-        lxw_drawing_free(worksheet->drawing);
-
-    free(worksheet->hbreaks);
-    free(worksheet->vbreaks);
-    free(worksheet->name);
-    free(worksheet->quoted_name);
-
-    free(worksheet);
-    worksheet = NULL;
-}
-
-/*
- * Create a new worksheet row object.
- */
-STATIC lxw_row *
-_new_row(lxw_row_t row_num)
-{
-    lxw_row *row = calloc(1, sizeof(lxw_row));
-
-    if (row) {
-        row->row_num = row_num;
-        row->cells = calloc(1, sizeof(struct lxw_table_cells));
-        row->height = LXW_DEF_ROW_HEIGHT;
-
-        if (row->cells)
-            RB_INIT(row->cells);
-        else
-            LXW_MEM_ERROR();
-    }
-    else {
-        LXW_MEM_ERROR();
-    }
-
-    return row;
-}
-
-/*
- * Create a new worksheet number cell object.
- */
-STATIC lxw_cell *
-_new_number_cell(lxw_row_t row_num,
-                 lxw_col_t col_num, double value, lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = NUMBER_CELL;
-    cell->format = format;
-    cell->u.number = value;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet string cell object.
- */
-STATIC lxw_cell *
-_new_string_cell(lxw_row_t row_num,
-                 lxw_col_t col_num, int32_t string_id, char *sst_string,
-                 lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = STRING_CELL;
-    cell->format = format;
-    cell->u.string_id = string_id;
-    cell->sst_string = sst_string;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet inline_string cell object.
- */
-STATIC lxw_cell *
-_new_inline_string_cell(lxw_row_t row_num,
-                        lxw_col_t col_num, char *string, lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = INLINE_STRING_CELL;
-    cell->format = format;
-    cell->u.string = string;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet formula cell object.
- */
-STATIC lxw_cell *
-_new_formula_cell(lxw_row_t row_num,
-                  lxw_col_t col_num, char *formula, lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = FORMULA_CELL;
-    cell->format = format;
-    cell->u.string = formula;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet array formula cell object.
- */
-STATIC lxw_cell *
-_new_array_formula_cell(lxw_row_t row_num, lxw_col_t col_num, char *formula,
-                        char *range, lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = ARRAY_FORMULA_CELL;
-    cell->format = format;
-    cell->u.string = formula;
-    cell->user_data1 = range;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet blank cell object.
- */
-STATIC lxw_cell *
-_new_blank_cell(lxw_row_t row_num, lxw_col_t col_num, lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = BLANK_CELL;
-    cell->format = format;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet boolean cell object.
- */
-STATIC lxw_cell *
-_new_boolean_cell(lxw_row_t row_num, lxw_col_t col_num, int value,
-                  lxw_format *format)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = BOOLEAN_CELL;
-    cell->format = format;
-    cell->u.number = value;
-
-    return cell;
-}
-
-/*
- * Create a new worksheet hyperlink cell object.
- */
-STATIC lxw_cell *
-_new_hyperlink_cell(lxw_row_t row_num, lxw_col_t col_num,
-                    enum cell_types link_type, char *url, char *string,
-                    char *tooltip)
-{
-    lxw_cell *cell = calloc(1, sizeof(lxw_cell));
-    RETURN_ON_MEM_ERROR(cell, cell);
-
-    cell->row_num = row_num;
-    cell->col_num = col_num;
-    cell->type = link_type;
-    cell->u.string = url;
-    cell->user_data1 = string;
-    cell->user_data2 = tooltip;
-
-    return cell;
-}
-
-/*
- * Get or create the row object for a given row number.
- */
-STATIC lxw_row *
-_get_row_list(struct lxw_table_rows *table, lxw_row_t row_num)
-{
-    lxw_row *row;
-    lxw_row *existing_row;
-
-    if (table->cached_row_num == row_num)
-        return table->cached_row;
-
-    /* Create a new row and try and insert it. */
-    row = _new_row(row_num);
-    existing_row = RB_INSERT(lxw_table_rows, table, row);
-
-    /* If existing_row is not NULL, then it already existed. Free new row */
-    /* and return existing_row. */
-    if (existing_row) {
-        _free_row(row);
-        row = existing_row;
-    }
-
-    table->cached_row = row;
-    table->cached_row_num = row_num;
-
-    return row;
-}
-
-/*
- * Get or create the row object for a given row number.
- */
-STATIC lxw_row *
-_get_row(lxw_worksheet *self, lxw_row_t row_num)
-{
-    lxw_row *row;
-
-    if (!self->optimize) {
-        row = _get_row_list(self->table, row_num);
-        return row;
-    }
-    else {
-        if (row_num < self->optimize_row->row_num) {
-            return NULL;
-        }
-        else if (row_num == self->optimize_row->row_num) {
-            return self->optimize_row;
-        }
-        else {
-            /* Flush row. */
-            lxw_worksheet_write_single_row(self);
-            row = self->optimize_row;
-            row->row_num = row_num;
-            return row;
-        }
-    }
-}
-
-/*
- * Insert a cell object in the cell list of a row object.
- */
-STATIC void
-_insert_cell_list(struct lxw_table_cells *cell_list,
-                  lxw_cell *cell, lxw_col_t col_num)
-{
-    lxw_cell *existing_cell;
-
-    cell->col_num = col_num;
-
-    existing_cell = RB_INSERT(lxw_table_cells, cell_list, cell);
-
-    /* If existing_cell is not NULL, then that cell already existed. */
-    /* Remove existing_cell and add new one in again. */
-    if (existing_cell) {
-        RB_REMOVE(lxw_table_cells, cell_list, existing_cell);
-
-        /* Add it in again. */
-        RB_INSERT(lxw_table_cells, cell_list, cell);
-        _free_cell(existing_cell);
-    }
-
-    return;
-}
-
-/*
- * Insert a cell object into the cell list or array.
- */
-STATIC void
-_insert_cell(lxw_worksheet *self, lxw_row_t row_num, lxw_col_t col_num,
-             lxw_cell *cell)
-{
-    lxw_row *row = _get_row(self, row_num);
-
-    if (!self->optimize) {
-        row->data_changed = LXW_TRUE;
-        _insert_cell_list(row->cells, cell, col_num);
-    }
-    else {
-        if (row) {
-            row->data_changed = LXW_TRUE;
-
-            /* Overwrite an existing cell if necessary. */
-            if (self->array[col_num])
-                _free_cell(self->array[col_num]);
-
-            self->array[col_num] = cell;
-        }
-    }
-}
-
-/*
- * Insert a hyperlink object into the hyperlink list.
- */
-STATIC void
-_insert_hyperlink(lxw_worksheet *self, lxw_row_t row_num, lxw_col_t col_num,
-                  lxw_cell *link)
-{
-    lxw_row *row = _get_row_list(self->hyperlinks, row_num);
-
-    _insert_cell_list(row->cells, link, col_num);
-}
-
-/*
- * Next power of two for column reallocs. Taken from bithacks in the public
- * domain.
- */
-STATIC lxw_col_t
-_next_power_of_two(uint16_t col)
-{
-    col--;
-    col |= col >> 1;
-    col |= col >> 2;
-    col |= col >> 4;
-    col |= col >> 8;
-    col++;
-
-    return col;
-}
-
-/*
- * Check that row and col are within the allowed Excel range and store max
- * and min values for use in other methods/elements.
- *
- * The ignore_row/ignore_col flags are used to indicate that we wish to
- * perform the dimension check without storing the value.
- */
-STATIC lxw_error
-_check_dimensions(lxw_worksheet *self,
-                  lxw_row_t row_num,
-                  lxw_col_t col_num, int8_t ignore_row, int8_t ignore_col)
-{
-    if (row_num >= LXW_ROW_MAX)
-        return LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE;
-
-    if (col_num >= LXW_COL_MAX)
-        return LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE;
-
-    /* In optimization mode we don't change dimensions for rows that are */
-    /* already written. */
-    if (!ignore_row && !ignore_col && self->optimize) {
-        if (row_num < self->optimize_row->row_num)
-            return LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE;
-    }
-
-    if (!ignore_row) {
-        if (row_num < self->dim_rowmin)
-            self->dim_rowmin = row_num;
-        if (row_num > self->dim_rowmax)
-            self->dim_rowmax = row_num;
-    }
-
-    if (!ignore_col) {
-        if (col_num < self->dim_colmin)
-            self->dim_colmin = col_num;
-        if (col_num > self->dim_colmax)
-            self->dim_colmax = col_num;
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Comparator for the row structure red/black tree.
- */
-STATIC int
-_row_cmp(lxw_row *row1, lxw_row *row2)
-{
-    if (row1->row_num > row2->row_num)
-        return 1;
-    if (row1->row_num < row2->row_num)
-        return -1;
-    return 0;
-}
-
-/*
- * Comparator for the cell structure red/black tree.
- */
-STATIC int
-_cell_cmp(lxw_cell *cell1, lxw_cell *cell2)
-{
-    if (cell1->col_num > cell2->col_num)
-        return 1;
-    if (cell1->col_num < cell2->col_num)
-        return -1;
-    return 0;
-}
-
-/*
- * Hash a worksheet password. Based on the algorithm provided by Daniel Rentz
- * of OpenOffice.
- */
-STATIC uint16_t
-_hash_password(const char *password)
-{
-    size_t count;
-    uint8_t i;
-    uint16_t hash = 0x0000;
-
-    count = strlen(password);
-
-    for (i = 0; i < count; i++) {
-        uint32_t low_15;
-        uint32_t high_15;
-        uint32_t letter = password[i] << (i + 1);
-
-        low_15 = letter & 0x7fff;
-        high_15 = letter & (0x7fff << 15);
-        high_15 = high_15 >> 15;
-        letter = low_15 | high_15;
-
-        hash ^= letter;
-    }
-
-    hash ^= count;
-    hash ^= 0xCE4B;
-
-    return hash;
-}
-
-/*
- * Simple replacement for libgen.h basename() for compatibility with MSVC. It
- * handles forward and back slashes. It doesn't copy exactly the return
- * format of basename().
- */
-char *
-lxw_basename(const char *path)
-{
-
-    char *forward_slash;
-    char *back_slash;
-
-    if (!path)
-        return NULL;
-
-    forward_slash = strrchr(path, '/');
-    back_slash = strrchr(path, '\\');
-
-    if (!forward_slash && !back_slash)
-        return (char *) path;
-
-    if (forward_slash > back_slash)
-        return forward_slash + 1;
-    else
-        return back_slash + 1;
-}
-
-/* Function to count the total concatenated length of the strings in a
- * validation list array, including commas. */
-size_t
-_validation_list_length(char **list)
-{
-    uint8_t i = 0;
-    size_t length = 0;
-
-    if (!list || !list[0])
-        return 0;
-
-    while (list[i] && length <= LXW_VALIDATION_MAX_STRING_LENGTH) {
-        /* Include commas in the length. */
-        length += 1 + lxw_utf8_strlen(list[i]);
-        i++;
-    }
-
-    /* Adjust the count for extraneous comma at end. */
-    length--;
-
-    return length;
-}
-
-/* Function to convert an array of strings into a CSV string for data
- * validation lists. */
-char *
-_validation_list_to_csv(char **list)
-{
-    uint8_t i = 0;
-    char *str;
-
-    /* Create a buffer for the concatenated, and quoted, string. */
-    /* Add +3 for quotes and EOL. */
-    str = calloc(1, LXW_VALIDATION_MAX_STRING_LENGTH + 3);
-    if (!str)
-        return NULL;
-
-    /* Add the start quote and first element. */
-    strcat(str, "\"");
-    strcat(str, list[0]);
-
-    /* Add the other elements preceded by a comma. */
-    i = 1;
-    while (list[i]) {
-        strcat(str, ",");
-        strcat(str, list[i]);
-        i++;
-    }
-
-    /* Add the end quote. */
-    strcat(str, "\"");
-
-    return str;
-}
-
-/*****************************************************************************
- *
- * XML functions.
- *
- ****************************************************************************/
-/*
- * Write the XML declaration.
- */
-STATIC void
-_worksheet_xml_declaration(lxw_worksheet *self)
-{
-    lxw_xml_declaration(self->file);
-}
-
-/*
- * Write the <worksheet> element.
- */
-STATIC void
-_worksheet_write_worksheet(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char xmlns[] = "http://schemas.openxmlformats.org/"
-        "spreadsheetml/2006/main";
-    char xmlns_r[] = "http://schemas.openxmlformats.org/"
-        "officeDocument/2006/relationships";
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
-    LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
-
-    lxw_xml_start_tag(self->file, "worksheet", &attributes);
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <dimension> element.
- */
-STATIC void
-_worksheet_write_dimension(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char ref[LXW_MAX_CELL_RANGE_LENGTH];
-    lxw_row_t dim_rowmin = self->dim_rowmin;
-    lxw_row_t dim_rowmax = self->dim_rowmax;
-    lxw_col_t dim_colmin = self->dim_colmin;
-    lxw_col_t dim_colmax = self->dim_colmax;
-
-    if (dim_rowmin == LXW_ROW_MAX && dim_colmin == LXW_COL_MAX) {
-        /* If the rows and cols are still the defaults then no dimensions have
-         * been set and we use the default range "A1". */
-        lxw_rowcol_to_range(ref, 0, 0, 0, 0);
-    }
-    else if (dim_rowmin == LXW_ROW_MAX && dim_colmin != LXW_COL_MAX) {
-        /* If the rows aren't set but the columns are then the dimensions have
-         * been changed via set_column(). */
-        lxw_rowcol_to_range(ref, 0, dim_colmin, 0, dim_colmax);
-    }
-    else {
-        lxw_rowcol_to_range(ref, dim_rowmin, dim_colmin, dim_rowmax,
-                            dim_colmax);
-    }
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("ref", ref);
-
-    lxw_xml_empty_tag(self->file, "dimension", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <pane> element for freeze panes.
- */
-STATIC void
-_worksheet_write_freeze_panes(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    lxw_selection *selection;
-    lxw_selection *user_selection;
-    lxw_row_t row = self->panes.first_row;
-    lxw_col_t col = self->panes.first_col;
-    lxw_row_t top_row = self->panes.top_row;
-    lxw_col_t left_col = self->panes.left_col;
-
-    char row_cell[LXW_MAX_CELL_NAME_LENGTH];
-    char col_cell[LXW_MAX_CELL_NAME_LENGTH];
-    char top_left_cell[LXW_MAX_CELL_NAME_LENGTH];
-    char active_pane[LXW_PANE_NAME_LENGTH];
-
-    /* If there is a user selection we remove it from the list and use it. */
-    if (!STAILQ_EMPTY(self->selections)) {
-        user_selection = STAILQ_FIRST(self->selections);
-        STAILQ_REMOVE_HEAD(self->selections, list_pointers);
-    }
-    else {
-        /* or else create a new blank selection. */
-        user_selection = calloc(1, sizeof(lxw_selection));
-        RETURN_VOID_ON_MEM_ERROR(user_selection);
-    }
-
-    LXW_INIT_ATTRIBUTES();
-
-    lxw_rowcol_to_cell(top_left_cell, top_row, left_col);
-
-    /* Set the active pane. */
-    if (row && col) {
-        lxw_strcpy(active_pane, "bottomRight");
-
-        lxw_rowcol_to_cell(row_cell, row, 0);
-        lxw_rowcol_to_cell(col_cell, 0, col);
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "topRight");
-            lxw_strcpy(selection->active_cell, col_cell);
-            lxw_strcpy(selection->sqref, col_cell);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "bottomLeft");
-            lxw_strcpy(selection->active_cell, row_cell);
-            lxw_strcpy(selection->sqref, row_cell);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "bottomRight");
-            lxw_strcpy(selection->active_cell, user_selection->active_cell);
-            lxw_strcpy(selection->sqref, user_selection->sqref);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-    }
-    else if (col) {
-        lxw_strcpy(active_pane, "topRight");
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "topRight");
-            lxw_strcpy(selection->active_cell, user_selection->active_cell);
-            lxw_strcpy(selection->sqref, user_selection->sqref);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-    }
-    else {
-        lxw_strcpy(active_pane, "bottomLeft");
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "bottomLeft");
-            lxw_strcpy(selection->active_cell, user_selection->active_cell);
-            lxw_strcpy(selection->sqref, user_selection->sqref);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-    }
-
-    if (col)
-        LXW_PUSH_ATTRIBUTES_INT("xSplit", col);
-
-    if (row)
-        LXW_PUSH_ATTRIBUTES_INT("ySplit", row);
-
-    LXW_PUSH_ATTRIBUTES_STR("topLeftCell", top_left_cell);
-    LXW_PUSH_ATTRIBUTES_STR("activePane", active_pane);
-
-    if (self->panes.type == FREEZE_PANES)
-        LXW_PUSH_ATTRIBUTES_STR("state", "frozen");
-    else if (self->panes.type == FREEZE_SPLIT_PANES)
-        LXW_PUSH_ATTRIBUTES_STR("state", "frozenSplit");
-
-    lxw_xml_empty_tag(self->file, "pane", &attributes);
-
-    free(user_selection);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Convert column width from user units to pane split width.
- */
-STATIC uint32_t
-_worksheet_calculate_x_split_width(double x_split)
-{
-    uint32_t width;
-    uint32_t pixels;
-    uint32_t points;
-    uint32_t twips;
-    double max_digit_width = 7.0;       /* For Calabri 11. */
-    double padding = 5.0;
-
-    /* Convert to pixels. */
-    if (x_split < 1.0) {
-        pixels = (uint32_t) (x_split * (max_digit_width + padding) + 0.5);
-    }
-    else {
-        pixels = (uint32_t) (x_split * max_digit_width + 0.5) + 5;
-    }
-
-    /* Convert to points. */
-    points = (pixels * 3) / 4;
-
-    /* Convert to twips (twentieths of a point). */
-    twips = points * 20;
-
-    /* Add offset/padding. */
-    width = twips + 390;
-
-    return width;
-}
-
-/*
- * Write the <pane> element for split panes.
- */
-STATIC void
-_worksheet_write_split_panes(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    lxw_selection *selection;
-    lxw_selection *user_selection;
-    lxw_row_t row = self->panes.first_row;
-    lxw_col_t col = self->panes.first_col;
-    lxw_row_t top_row = self->panes.top_row;
-    lxw_col_t left_col = self->panes.left_col;
-    double x_split = self->panes.x_split;
-    double y_split = self->panes.y_split;
-    uint8_t has_selection = LXW_FALSE;
-
-    char row_cell[LXW_MAX_CELL_NAME_LENGTH];
-    char col_cell[LXW_MAX_CELL_NAME_LENGTH];
-    char top_left_cell[LXW_MAX_CELL_NAME_LENGTH];
-    char active_pane[LXW_PANE_NAME_LENGTH];
-
-    /* If there is a user selection we remove it from the list and use it. */
-    if (!STAILQ_EMPTY(self->selections)) {
-        user_selection = STAILQ_FIRST(self->selections);
-        STAILQ_REMOVE_HEAD(self->selections, list_pointers);
-        has_selection = LXW_TRUE;
-    }
-    else {
-        /* or else create a new blank selection. */
-        user_selection = calloc(1, sizeof(lxw_selection));
-        RETURN_VOID_ON_MEM_ERROR(user_selection);
-    }
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Convert the row and col to 1/20 twip units with padding. */
-    if (y_split > 0.0)
-        y_split = (uint32_t) (20 * y_split + 300);
-
-    if (x_split > 0.0)
-        x_split = _worksheet_calculate_x_split_width(x_split);
-
-    /* For non-explicit topLeft definitions, estimate the cell offset based on
-     * the pixels dimensions. This is only a workaround and doesn't take
-     * adjusted cell dimensions into account.
-     */
-    if (top_row == row && left_col == col) {
-        top_row = (lxw_row_t) (0.5 + (y_split - 300.0) / 20.0 / 15.0);
-        left_col = (lxw_col_t) (0.5 + (x_split - 390.0) / 20.0 / 3.0 / 16.0);
-    }
-
-    lxw_rowcol_to_cell(top_left_cell, top_row, left_col);
-
-    /* If there is no selection set the active cell to the top left cell. */
-    if (!has_selection) {
-        lxw_strcpy(user_selection->active_cell, top_left_cell);
-        lxw_strcpy(user_selection->sqref, top_left_cell);
-    }
-
-    /* Set the active pane. */
-    if (y_split > 0.0 && x_split > 0.0) {
-        lxw_strcpy(active_pane, "bottomRight");
-
-        lxw_rowcol_to_cell(row_cell, top_row, 0);
-        lxw_rowcol_to_cell(col_cell, 0, left_col);
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "topRight");
-            lxw_strcpy(selection->active_cell, col_cell);
-            lxw_strcpy(selection->sqref, col_cell);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "bottomLeft");
-            lxw_strcpy(selection->active_cell, row_cell);
-            lxw_strcpy(selection->sqref, row_cell);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "bottomRight");
-            lxw_strcpy(selection->active_cell, user_selection->active_cell);
-            lxw_strcpy(selection->sqref, user_selection->sqref);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-    }
-    else if (x_split > 0.0) {
-        lxw_strcpy(active_pane, "topRight");
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "topRight");
-            lxw_strcpy(selection->active_cell, user_selection->active_cell);
-            lxw_strcpy(selection->sqref, user_selection->sqref);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-    }
-    else {
-        lxw_strcpy(active_pane, "bottomLeft");
-
-        selection = calloc(1, sizeof(lxw_selection));
-        if (selection) {
-            lxw_strcpy(selection->pane, "bottomLeft");
-            lxw_strcpy(selection->active_cell, user_selection->active_cell);
-            lxw_strcpy(selection->sqref, user_selection->sqref);
-
-            STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-        }
-    }
-
-    if (x_split > 0.0)
-        LXW_PUSH_ATTRIBUTES_DBL("xSplit", x_split);
-
-    if (y_split > 0.0)
-        LXW_PUSH_ATTRIBUTES_DBL("ySplit", y_split);
-
-    LXW_PUSH_ATTRIBUTES_STR("topLeftCell", top_left_cell);
-
-    if (has_selection)
-        LXW_PUSH_ATTRIBUTES_STR("activePane", active_pane);
-
-    lxw_xml_empty_tag(self->file, "pane", &attributes);
-
-    free(user_selection);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <selection> element.
- */
-STATIC void
-_worksheet_write_selection(lxw_worksheet *self, lxw_selection *selection)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (*selection->pane)
-        LXW_PUSH_ATTRIBUTES_STR("pane", selection->pane);
-
-    if (*selection->active_cell)
-        LXW_PUSH_ATTRIBUTES_STR("activeCell", selection->active_cell);
-
-    if (*selection->sqref)
-        LXW_PUSH_ATTRIBUTES_STR("sqref", selection->sqref);
-
-    lxw_xml_empty_tag(self->file, "selection", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <selection> elements.
- */
-STATIC void
-_worksheet_write_selections(lxw_worksheet *self)
-{
-    lxw_selection *selection;
-
-    STAILQ_FOREACH(selection, self->selections, list_pointers) {
-        _worksheet_write_selection(self, selection);
-    }
-}
-
-/*
- * Write the frozen or split <pane> elements.
- */
-STATIC void
-_worksheet_write_panes(lxw_worksheet *self)
-{
-    if (self->panes.type == NO_PANES)
-        return;
-
-    else if (self->panes.type == FREEZE_PANES)
-        _worksheet_write_freeze_panes(self);
-
-    else if (self->panes.type == FREEZE_SPLIT_PANES)
-        _worksheet_write_freeze_panes(self);
-
-    else if (self->panes.type == SPLIT_PANES)
-        _worksheet_write_split_panes(self);
-}
-
-/*
- * Write the <sheetView> element.
- */
-STATIC void
-_worksheet_write_sheet_view(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Hide screen gridlines if required */
-    if (!self->screen_gridlines)
-        LXW_PUSH_ATTRIBUTES_STR("showGridLines", "0");
-
-    /* Hide zeroes in cells. */
-    if (!self->show_zeros) {
-        LXW_PUSH_ATTRIBUTES_STR("showZeros", "0");
-    }
-
-    /* Display worksheet right to left for Hebrew, Arabic and others. */
-    if (self->right_to_left) {
-        LXW_PUSH_ATTRIBUTES_STR("rightToLeft", "1");
-    }
-
-    /* Show that the sheet tab is selected. */
-    if (self->selected)
-        LXW_PUSH_ATTRIBUTES_STR("tabSelected", "1");
-
-    /* Turn outlines off. Also required in the outlinePr element. */
-    if (!self->outline_on) {
-        LXW_PUSH_ATTRIBUTES_STR("showOutlineSymbols", "0");
-    }
-
-    /* Set the page view/layout mode if required. */
-    if (self->page_view)
-        LXW_PUSH_ATTRIBUTES_STR("view", "pageLayout");
-
-    /* Set the zoom level. */
-    if (self->zoom != 100) {
-        if (!self->page_view) {
-            LXW_PUSH_ATTRIBUTES_INT("zoomScale", self->zoom);
-
-            if (self->zoom_scale_normal)
-                LXW_PUSH_ATTRIBUTES_INT("zoomScaleNormal", self->zoom);
-        }
-    }
-
-    LXW_PUSH_ATTRIBUTES_STR("workbookViewId", "0");
-
-    if (self->panes.type != NO_PANES || !STAILQ_EMPTY(self->selections)) {
-        lxw_xml_start_tag(self->file, "sheetView", &attributes);
-        _worksheet_write_panes(self);
-        _worksheet_write_selections(self);
-        lxw_xml_end_tag(self->file, "sheetView");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "sheetView", &attributes);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <sheetViews> element.
- */
-STATIC void
-_worksheet_write_sheet_views(lxw_worksheet *self)
-{
-    lxw_xml_start_tag(self->file, "sheetViews", NULL);
-
-    /* Write the sheetView element. */
-    _worksheet_write_sheet_view(self);
-
-    lxw_xml_end_tag(self->file, "sheetViews");
-}
-
-/*
- * Write the <sheetFormatPr> element.
- */
-STATIC void
-_worksheet_write_sheet_format_pr(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("defaultRowHeight", self->default_row_height);
-
-    if (self->default_row_height != LXW_DEF_ROW_HEIGHT)
-        LXW_PUSH_ATTRIBUTES_STR("customHeight", "1");
-
-    if (self->default_row_zeroed)
-        LXW_PUSH_ATTRIBUTES_STR("zeroHeight", "1");
-
-    if (self->outline_row_level)
-        LXW_PUSH_ATTRIBUTES_INT("outlineLevelRow", self->outline_row_level);
-
-    if (self->outline_col_level)
-        LXW_PUSH_ATTRIBUTES_INT("outlineLevelCol", self->outline_col_level);
-
-    lxw_xml_empty_tag(self->file, "sheetFormatPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <sheetData> element.
- */
-STATIC void
-_worksheet_write_sheet_data(lxw_worksheet *self)
-{
-    if (RB_EMPTY(self->table)) {
-        lxw_xml_empty_tag(self->file, "sheetData", NULL);
-    }
-    else {
-        lxw_xml_start_tag(self->file, "sheetData", NULL);
-        _worksheet_write_rows(self);
-        lxw_xml_end_tag(self->file, "sheetData");
-    }
-}
-
-/*
- * Write the <sheetData> element when the memory optimization is on. In which
- * case we read the data stored in the temp file and rewrite it to the XML
- * sheet file.
- */
-STATIC void
-_worksheet_write_optimized_sheet_data(lxw_worksheet *self)
-{
-    size_t read_size = 1;
-    char buffer[LXW_BUFFER_SIZE];
-
-    if (self->dim_rowmin == LXW_ROW_MAX) {
-        /* If the dimensions aren't defined then there is no data to write. */
-        lxw_xml_empty_tag(self->file, "sheetData", NULL);
-    }
-    else {
-
-        lxw_xml_start_tag(self->file, "sheetData", NULL);
-
-        /* Flush and rewind the temp file. */
-        fflush(self->optimize_tmpfile);
-        rewind(self->optimize_tmpfile);
-
-        while (read_size) {
-            read_size =
-                fread(buffer, 1, LXW_BUFFER_SIZE, self->optimize_tmpfile);
-            fwrite(buffer, 1, read_size, self->file);
-        }
-
-        fclose(self->optimize_tmpfile);
-
-        lxw_xml_end_tag(self->file, "sheetData");
-    }
-}
-
-/*
- * Write the <pageMargins> element.
- */
-STATIC void
-_worksheet_write_page_margins(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    double left = self->margin_left;
-    double right = self->margin_right;
-    double top = self->margin_top;
-    double bottom = self->margin_bottom;
-    double header = self->margin_header;
-    double footer = self->margin_footer;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_DBL("left", left);
-    LXW_PUSH_ATTRIBUTES_DBL("right", right);
-    LXW_PUSH_ATTRIBUTES_DBL("top", top);
-    LXW_PUSH_ATTRIBUTES_DBL("bottom", bottom);
-    LXW_PUSH_ATTRIBUTES_DBL("header", header);
-    LXW_PUSH_ATTRIBUTES_DBL("footer", footer);
-
-    lxw_xml_empty_tag(self->file, "pageMargins", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <pageSetup> element.
- * The following is an example taken from Excel.
- * <pageSetup
- *     paperSize="9"
- *     scale="110"
- *     fitToWidth="2"
- *     fitToHeight="2"
- *     pageOrder="overThenDown"
- *     orientation="portrait"
- *     blackAndWhite="1"
- *     draft="1"
- *     horizontalDpi="200"
- *     verticalDpi="200"
- *     r:id="rId1"
- * />
- */
-STATIC void
-_worksheet_write_page_setup(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (!self->page_setup_changed)
-        return;
-
-    /* Set paper size. */
-    if (self->paper_size)
-        LXW_PUSH_ATTRIBUTES_INT("paperSize", self->paper_size);
-
-    /* Set the print_scale. */
-    if (self->print_scale != 100)
-        LXW_PUSH_ATTRIBUTES_INT("scale", self->print_scale);
-
-    /* Set the "Fit to page" properties. */
-    if (self->fit_page && self->fit_width != 1)
-        LXW_PUSH_ATTRIBUTES_INT("fitToWidth", self->fit_width);
-
-    if (self->fit_page && self->fit_height != 1)
-        LXW_PUSH_ATTRIBUTES_INT("fitToHeight", self->fit_height);
-
-    /* Set the page print direction. */
-    if (self->page_order)
-        LXW_PUSH_ATTRIBUTES_STR("pageOrder", "overThenDown");
-
-    /* Set start page. */
-    if (self->page_start > 1)
-        LXW_PUSH_ATTRIBUTES_INT("firstPageNumber", self->page_start);
-
-    /* Set page orientation. */
-    if (self->orientation)
-        LXW_PUSH_ATTRIBUTES_STR("orientation", "portrait");
-    else
-        LXW_PUSH_ATTRIBUTES_STR("orientation", "landscape");
-
-    /* Set start page active flag. */
-    if (self->page_start)
-        LXW_PUSH_ATTRIBUTES_INT("useFirstPageNumber", 1);
-
-    /* Set the DPI. Mainly only for testing. */
-    if (self->horizontal_dpi)
-        LXW_PUSH_ATTRIBUTES_INT("horizontalDpi", self->horizontal_dpi);
-
-    if (self->vertical_dpi)
-        LXW_PUSH_ATTRIBUTES_INT("verticalDpi", self->vertical_dpi);
-
-    lxw_xml_empty_tag(self->file, "pageSetup", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <printOptions> element.
- */
-STATIC void
-_worksheet_write_print_options(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    if (!self->print_options_changed)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Set horizontal centering. */
-    if (self->hcenter) {
-        LXW_PUSH_ATTRIBUTES_STR("horizontalCentered", "1");
-    }
-
-    /* Set vertical centering. */
-    if (self->vcenter) {
-        LXW_PUSH_ATTRIBUTES_STR("verticalCentered", "1");
-    }
-
-    /* Enable row and column headers. */
-    if (self->print_headers) {
-        LXW_PUSH_ATTRIBUTES_STR("headings", "1");
-    }
-
-    /* Set printed gridlines. */
-    if (self->print_gridlines) {
-        LXW_PUSH_ATTRIBUTES_STR("gridLines", "1");
-    }
-
-    lxw_xml_empty_tag(self->file, "printOptions", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <row> element.
- */
-STATIC void
-_write_row(lxw_worksheet *self, lxw_row *row, char *spans)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    int32_t xf_index = 0;
-    double height;
-
-    if (row->format) {
-        xf_index = lxw_format_get_xf_index(row->format);
-    }
-
-    if (row->height_changed)
-        height = row->height;
-    else
-        height = self->default_row_height;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("r", row->row_num + 1);
-
-    if (spans)
-        LXW_PUSH_ATTRIBUTES_STR("spans", spans);
-
-    if (xf_index)
-        LXW_PUSH_ATTRIBUTES_INT("s", xf_index);
-
-    if (row->format)
-        LXW_PUSH_ATTRIBUTES_STR("customFormat", "1");
-
-    if (height != LXW_DEF_ROW_HEIGHT)
-        LXW_PUSH_ATTRIBUTES_DBL("ht", height);
-
-    if (row->hidden)
-        LXW_PUSH_ATTRIBUTES_STR("hidden", "1");
-
-    if (height != LXW_DEF_ROW_HEIGHT)
-        LXW_PUSH_ATTRIBUTES_STR("customHeight", "1");
-
-    if (row->level)
-        LXW_PUSH_ATTRIBUTES_INT("outlineLevel", row->level);
-
-    if (row->collapsed)
-        LXW_PUSH_ATTRIBUTES_STR("collapsed", "1");
-
-    if (!row->data_changed)
-        lxw_xml_empty_tag(self->file, "row", &attributes);
-    else
-        lxw_xml_start_tag(self->file, "row", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Convert the width of a cell from user's units to pixels. Excel rounds the
- * column width to the nearest pixel. If the width hasn't been set by the user
- * we use the default value. If the column is hidden it has a value of zero.
- */
-STATIC int32_t
-_worksheet_size_col(lxw_worksheet *self, lxw_col_t col_num)
-{
-    lxw_col_options *col_opt = NULL;
-    uint32_t pixels;
-    double width;
-    double max_digit_width = 7.0;       /* For Calabri 11. */
-    double padding = 5.0;
-    lxw_col_t col_index;
-
-    /* Search for the col number in the array of col_options. Each col_option
-     * entry contains the start and end column for a range.
-     */
-    for (col_index = 0; col_index < self->col_options_max; col_index++) {
-        col_opt = self->col_options[col_index];
-
-        if (col_opt) {
-            if (col_num >= col_opt->firstcol && col_num <= col_opt->lastcol)
-                break;
-            else
-                col_opt = NULL;
-        }
-    }
-
-    if (col_opt) {
-        width = col_opt->width;
-
-        /* Convert to pixels. */
-        if (width == 0) {
-            pixels = 0;
-        }
-        else if (width < 1.0) {
-            pixels = (uint32_t) (width * (max_digit_width + padding) + 0.5);
-        }
-        else {
-            pixels = (uint32_t) (width * max_digit_width + 0.5) + 5;
-        }
-    }
-    else {
-        pixels = self->default_col_pixels;
-    }
-
-    return pixels;
-}
-
-/*
- * Convert the height of a cell from user's units to pixels. If the height
- * hasn't been set by the user we use the default value. If the row is hidden
- * it has a value of zero.
- */
-STATIC int32_t
-_worksheet_size_row(lxw_worksheet *self, lxw_row_t row_num)
-{
-    lxw_row *row;
-    uint32_t pixels;
-    double height;
-
-    row = lxw_worksheet_find_row(self, row_num);
-
-    if (row) {
-        height = row->height;
-
-        if (height == 0)
-            pixels = 0;
-        else
-            pixels = (uint32_t) (4.0 / 3.0 * height);
-    }
-    else {
-        pixels = (uint32_t) (4.0 / 3.0 * self->default_row_height);
-    }
-
-    return pixels;
-}
-
-/*
- * Calculate the vertices that define the position of a graphical object
- * within the worksheet in pixels.
- *         +------------+------------+
- *         |     A      |      B     |
- *   +-----+------------+------------+
- *   |     |(x1,y1)     |            |
- *   |  1  |(A1)._______|______      |
- *   |     |    |              |     |
- *   |     |    |              |     |
- *   +-----+----|    BITMAP    |-----+
- *   |     |    |              |     |
- *   |  2  |    |______________.     |
- *   |     |            |        (B2)|
- *   |     |            |     (x2,y2)|
- *   +---- +------------+------------+
- *
- * Example of an object that covers some of the area from cell A1 to cell B2.
- * Based on the width and height of the object we need to calculate 8 vars:
- *
- *     col_start, row_start, col_end, row_end, x1, y1, x2, y2.
- *
- * We also calculate the absolute x and y position of the top left vertex of
- * the object. This is required for images:
- *
- *    x_abs, y_abs
- *
- * The width and height of the cells that the object occupies can be variable
- * and have to be taken into account.
- *
- * The values of col_start and row_start are passed in from the calling
- * function. The values of col_end and row_end are calculated by subtracting
- * the width and height of the object from the width and height of the
- * underlying cells.
- */
-STATIC void
-_worksheet_position_object_pixels(lxw_worksheet *self,
-                                  lxw_image_options *image,
-                                  lxw_drawing_object *drawing_object)
-{
-    lxw_col_t col_start;        /* Column containing upper left corner.  */
-    int32_t x1;                 /* Distance to left side of object.      */
-
-    lxw_row_t row_start;        /* Row containing top left corner.       */
-    int32_t y1;                 /* Distance to top of object.            */
-
-    lxw_col_t col_end;          /* Column containing lower right corner. */
-    double x2;                  /* Distance to right side of object.     */
-
-    lxw_row_t row_end;          /* Row containing bottom right corner.   */
-    double y2;                  /* Distance to bottom of object.         */
-
-    double width;               /* Width of object frame.                */
-    double height;              /* Height of object frame.               */
-
-    uint32_t x_abs = 0;         /* Abs. distance to left side of object. */
-    uint32_t y_abs = 0;         /* Abs. distance to top  side of object. */
-
-    uint32_t i;
-
-    col_start = image->col;
-    row_start = image->row;
-    x1 = image->x_offset;
-    y1 = image->y_offset;
-    width = image->width;
-    height = image->height;
-
-    /* Adjust start column for negative offsets. */
-    while (x1 < 0 && col_start > 0) {
-        x1 += _worksheet_size_col(self, col_start - 1);
-        col_start--;
-    }
-
-    /* Adjust start row for negative offsets. */
-    while (y1 < 0 && row_start > 0) {
-        y1 += _worksheet_size_row(self, row_start - 1);
-        row_start--;
-    }
-
-    /* Ensure that the image isn't shifted off the page at top left. */
-    if (x1 < 0)
-        x1 = 0;
-
-    if (y1 < 0)
-        y1 = 0;
-
-    /* Calculate the absolute x offset of the top-left vertex. */
-    if (self->col_size_changed) {
-        for (i = 0; i < col_start; i++)
-            x_abs += _worksheet_size_col(self, i);
-    }
-    else {
-        /* Optimization for when the column widths haven't changed. */
-        x_abs += self->default_col_pixels * col_start;
-    }
-
-    x_abs += x1;
-
-    /* Calculate the absolute y offset of the top-left vertex. */
-    /* Store the column change to allow optimizations. */
-    if (self->row_size_changed) {
-        for (i = 0; i < row_start; i++)
-            y_abs += _worksheet_size_row(self, i);
-    }
-    else {
-        /* Optimization for when the row heights haven"t changed. */
-        y_abs += self->default_row_pixels * row_start;
-    }
-
-    y_abs += y1;
-
-    /* Adjust start col for offsets that are greater than the col width. */
-    while (x1 >= _worksheet_size_col(self, col_start)) {
-        x1 -= _worksheet_size_col(self, col_start);
-        col_start++;
-    }
-
-    /* Adjust start row for offsets that are greater than the row height. */
-    while (y1 >= _worksheet_size_row(self, row_start)) {
-        y1 -= _worksheet_size_row(self, row_start);
-        row_start++;
-    }
-
-    /* Initialize end cell to the same as the start cell. */
-    col_end = col_start;
-    row_end = row_start;
-
-    width = width + x1;
-    height = height + y1;
-
-    /* Subtract the underlying cell widths to find the end cell. */
-    while (width >= _worksheet_size_col(self, col_end)) {
-        width -= _worksheet_size_col(self, col_end);
-        col_end++;
-    }
-
-    /* Subtract the underlying cell heights to find the end cell. */
-    while (height >= _worksheet_size_row(self, row_end)) {
-        height -= _worksheet_size_row(self, row_end);
-        row_end++;
-    }
-
-    /* The end vertices are whatever is left from the width and height. */
-    x2 = width;
-    y2 = height;
-
-    /* Add the dimensions to the drawing object. */
-    drawing_object->from.col = col_start;
-    drawing_object->from.row = row_start;
-    drawing_object->from.col_offset = x1;
-    drawing_object->from.row_offset = y1;
-    drawing_object->to.col = col_end;
-    drawing_object->to.row = row_end;
-    drawing_object->to.col_offset = x2;
-    drawing_object->to.row_offset = y2;
-    drawing_object->col_absolute = x_abs;
-    drawing_object->row_absolute = y_abs;
-
-}
-
-/*
- * Calculate the vertices that define the position of a graphical object
- * within the worksheet in EMUs. The vertices are expressed as English
- * Metric Units (EMUs). There are 12,700 EMUs per point.
- * Therefore, 12,700 * 3 /4 = 9,525 EMUs per pixel.
- */
-STATIC void
-_worksheet_position_object_emus(lxw_worksheet *self,
-                                lxw_image_options *image,
-                                lxw_drawing_object *drawing_object)
-{
-
-    _worksheet_position_object_pixels(self, image, drawing_object);
-
-    /* Convert the pixel values to EMUs. See above. */
-    drawing_object->from.col_offset *= 9525;
-    drawing_object->from.row_offset *= 9525;
-    drawing_object->to.col_offset *= 9525;
-    drawing_object->to.row_offset *= 9525;
-    drawing_object->to.col_offset += 0.5;
-    drawing_object->to.row_offset += 0.5;
-    drawing_object->col_absolute *= 9525;
-    drawing_object->row_absolute *= 9525;
-}
-
-/*
- * Set up image/drawings.
- */
-void
-lxw_worksheet_prepare_image(lxw_worksheet *self,
-                            uint16_t image_ref_id, uint16_t drawing_id,
-                            lxw_image_options *image_data)
-{
-    lxw_drawing_object *drawing_object;
-    lxw_rel_tuple *relationship;
-    double width;
-    double height;
-    char filename[LXW_FILENAME_LENGTH];
-
-    if (!self->drawing) {
-        self->drawing = lxw_drawing_new();
-        self->drawing->embedded = LXW_TRUE;
-        RETURN_VOID_ON_MEM_ERROR(self->drawing);
-
-        relationship = calloc(1, sizeof(lxw_rel_tuple));
-        GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
-
-        relationship->type = lxw_strdup("/drawing");
-        GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
-
-        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
-                     "../drawings/drawing%d.xml", drawing_id);
-
-        relationship->target = lxw_strdup(filename);
-        GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
-
-        STAILQ_INSERT_TAIL(self->external_drawing_links, relationship,
-                           list_pointers);
-    }
-
-    drawing_object = calloc(1, sizeof(lxw_drawing_object));
-    RETURN_VOID_ON_MEM_ERROR(drawing_object);
-
-    drawing_object->anchor_type = LXW_ANCHOR_TYPE_IMAGE;
-    drawing_object->edit_as = LXW_ANCHOR_EDIT_AS_ONE_CELL;
-    drawing_object->description = lxw_strdup(image_data->short_name);
-
-    /* Scale to user scale. */
-    width = image_data->width * image_data->x_scale;
-    height = image_data->height * image_data->y_scale;
-
-    /* Scale by non 96dpi resolutions. */
-    width *= 96.0 / image_data->x_dpi;
-    height *= 96.0 / image_data->y_dpi;
-
-    /* Convert to the nearest pixel. */
-    image_data->width = width;
-    image_data->height = height;
-
-    _worksheet_position_object_emus(self, image_data, drawing_object);
-
-    /* Convert from pixels to emus. */
-    drawing_object->width = (uint32_t) (0.5 + width * 9525);
-    drawing_object->height = (uint32_t) (0.5 + height * 9525);
-
-    lxw_add_drawing_object(self->drawing, drawing_object);
-
-    relationship = calloc(1, sizeof(lxw_rel_tuple));
-    GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
-
-    relationship->type = lxw_strdup("/image");
-    GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
-
-    lxw_snprintf(filename, 32, "../media/image%d.%s", image_ref_id,
-                 image_data->extension);
-
-    relationship->target = lxw_strdup(filename);
-    GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
-
-    STAILQ_INSERT_TAIL(self->drawing_links, relationship, list_pointers);
-
-    return;
-
-mem_error:
-    if (relationship) {
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-}
-
-/*
- * Set up chart/drawings.
- */
-void
-lxw_worksheet_prepare_chart(lxw_worksheet *self,
-                            uint16_t chart_ref_id, uint16_t drawing_id,
-                            lxw_image_options *image_data)
-{
-    lxw_drawing_object *drawing_object;
-    lxw_rel_tuple *relationship;
-    double width;
-    double height;
-    char filename[LXW_FILENAME_LENGTH];
-
-    if (!self->drawing) {
-        self->drawing = lxw_drawing_new();
-        self->drawing->embedded = LXW_TRUE;
-        RETURN_VOID_ON_MEM_ERROR(self->drawing);
-
-        relationship = calloc(1, sizeof(lxw_rel_tuple));
-        GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
-
-        relationship->type = lxw_strdup("/drawing");
-        GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
-
-        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
-                     "../drawings/drawing%d.xml", drawing_id);
-
-        relationship->target = lxw_strdup(filename);
-        GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
-
-        STAILQ_INSERT_TAIL(self->external_drawing_links, relationship,
-                           list_pointers);
-    }
-
-    drawing_object = calloc(1, sizeof(lxw_drawing_object));
-    RETURN_VOID_ON_MEM_ERROR(drawing_object);
-
-    drawing_object->anchor_type = LXW_ANCHOR_TYPE_CHART;
-    drawing_object->edit_as = LXW_ANCHOR_EDIT_AS_ONE_CELL;
-    drawing_object->description = lxw_strdup("TODO_DESC");
-
-    /* Scale to user scale. */
-    width = image_data->width * image_data->x_scale;
-    height = image_data->height * image_data->y_scale;
-
-    /* Convert to the nearest pixel. */
-    image_data->width = width;
-    image_data->height = height;
-
-    _worksheet_position_object_emus(self, image_data, drawing_object);
-
-    /* Convert from pixels to emus. */
-    drawing_object->width = (uint32_t) (0.5 + width * 9525);
-    drawing_object->height = (uint32_t) (0.5 + height * 9525);
-
-    lxw_add_drawing_object(self->drawing, drawing_object);
-
-    relationship = calloc(1, sizeof(lxw_rel_tuple));
-    GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
-
-    relationship->type = lxw_strdup("/chart");
-    GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
-
-    lxw_snprintf(filename, 32, "../charts/chart%d.xml", chart_ref_id);
-
-    relationship->target = lxw_strdup(filename);
-    GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
-
-    STAILQ_INSERT_TAIL(self->drawing_links, relationship, list_pointers);
-
-    return;
-
-mem_error:
-    if (relationship) {
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-}
-
-/*
- * Extract width and height information from a PNG file.
- */
-STATIC lxw_error
-_process_png(lxw_image_options *image_options)
-{
-    uint32_t length;
-    uint32_t offset;
-    char type[4];
-    uint32_t width = 0;
-    uint32_t height = 0;
-    double x_dpi = 96;
-    double y_dpi = 96;
-    int fseek_err;
-
-    FILE *stream = image_options->stream;
-
-    /* Skip another 4 bytes to the end of the PNG header. */
-    fseek_err = fseek(stream, 4, SEEK_CUR);
-    if (fseek_err)
-        goto file_error;
-
-    while (!feof(stream)) {
-
-        /* Read the PNG length and type fields for the sub-section. */
-        if (fread(&length, sizeof(length), 1, stream) < 1)
-            break;
-
-        if (fread(&type, 1, 4, stream) < 4)
-            break;
-
-        /* Convert the length to network order. */
-        length = LXW_UINT32_NETWORK(length);
-
-        /* The offset for next fseek() is the field length + type length. */
-        offset = length + 4;
-
-        if (memcmp(type, "IHDR", 4) == 0) {
-            if (fread(&width, sizeof(width), 1, stream) < 1)
-                break;
-
-            if (fread(&height, sizeof(height), 1, stream) < 1)
-                break;
-
-            width = LXW_UINT32_NETWORK(width);
-            height = LXW_UINT32_NETWORK(height);
-
-            /* Reduce the offset by the length of previous freads(). */
-            offset -= 8;
-        }
-
-        if (memcmp(type, "pHYs", 4) == 0) {
-            uint32_t x_ppu = 0;
-            uint32_t y_ppu = 0;
-            uint8_t units = 1;
-
-            if (fread(&x_ppu, sizeof(x_ppu), 1, stream) < 1)
-                break;
-
-            if (fread(&y_ppu, sizeof(y_ppu), 1, stream) < 1)
-                break;
-
-            if (fread(&units, sizeof(units), 1, stream) < 1)
-                break;
-
-            if (units == 1) {
-                x_ppu = LXW_UINT32_NETWORK(x_ppu);
-                y_ppu = LXW_UINT32_NETWORK(y_ppu);
-
-                x_dpi = (double) x_ppu *0.0254;
-                y_dpi = (double) y_ppu *0.0254;
-            }
-
-            /* Reduce the offset by the length of previous freads(). */
-            offset -= 9;
-        }
-
-        if (memcmp(type, "IEND", 4) == 0)
-            break;
-
-        if (!feof(stream)) {
-            fseek_err = fseek(stream, offset, SEEK_CUR);
-            if (fseek_err)
-                goto file_error;
-        }
-    }
-
-    /* Ensure that we read some valid data from the file. */
-    if (width == 0)
-        goto file_error;
-
-    /* Set the image metadata. */
-    image_options->image_type = LXW_IMAGE_PNG;
-    image_options->width = width;
-    image_options->height = height;
-    image_options->x_dpi = x_dpi ? x_dpi : 96;
-    image_options->y_dpi = y_dpi ? x_dpi : 96;
-    image_options->extension = lxw_strdup("png");
-
-    return LXW_NO_ERROR;
-
-file_error:
-    LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                     "no size data found in file: %s.",
-                     image_options->filename);
-
-    return LXW_ERROR_IMAGE_DIMENSIONS;
-}
-
-/*
- * Extract width and height information from a JPEG file.
- */
-STATIC lxw_error
-_process_jpeg(lxw_image_options *image_options)
-{
-    uint16_t length;
-    uint16_t marker;
-    uint32_t offset;
-    uint16_t width = 0;
-    uint16_t height = 0;
-    double x_dpi = 96;
-    double y_dpi = 96;
-    int fseek_err;
-
-    FILE *stream = image_options->stream;
-
-    /* Read back 2 bytes to the end of the initial 0xFFD8 marker. */
-    fseek_err = fseek(stream, -2, SEEK_CUR);
-    if (fseek_err)
-        goto file_error;
-
-    /* Search through the image data and read the JPEG markers. */
-    while (!feof(stream)) {
-
-        /* Read the JPEG marker and length fields for the sub-section. */
-        if (fread(&marker, sizeof(marker), 1, stream) < 1)
-            break;
-
-        if (fread(&length, sizeof(length), 1, stream) < 1)
-            break;
-
-        /* Convert the marker and length to network order. */
-        marker = LXW_UINT16_NETWORK(marker);
-        length = LXW_UINT16_NETWORK(length);
-
-        /* The offset for next fseek() is the field length + type length. */
-        offset = length - 2;
-
-        /* Read the height and width in the 0xFFCn elements (except C4, C8 */
-        /* and CC which aren't SOF markers). */
-        if ((marker & 0xFFF0) == 0xFFC0 && marker != 0xFFC4
-            && marker != 0xFFC8 && marker != 0xFFCC) {
-            /* Skip 1 byte to height and width. */
-            fseek_err = fseek(stream, 1, SEEK_CUR);
-            if (fseek_err)
-                goto file_error;
-
-            if (fread(&height, sizeof(height), 1, stream) < 1)
-                break;
-
-            if (fread(&width, sizeof(width), 1, stream) < 1)
-                break;
-
-            height = LXW_UINT16_NETWORK(height);
-            width = LXW_UINT16_NETWORK(width);
-
-            offset -= 9;
-        }
-
-        /* Read the DPI in the 0xFFE0 element. */
-        if (marker == 0xFFE0) {
-            uint16_t x_density = 0;
-            uint16_t y_density = 0;
-            uint8_t units = 1;
-
-            fseek_err = fseek(stream, 7, SEEK_CUR);
-            if (fseek_err)
-                goto file_error;
-
-            if (fread(&units, sizeof(units), 1, stream) < 1)
-                break;
-
-            if (fread(&x_density, sizeof(x_density), 1, stream) < 1)
-                break;
-
-            if (fread(&y_density, sizeof(y_density), 1, stream) < 1)
-                break;
-
-            x_density = LXW_UINT16_NETWORK(x_density);
-            y_density = LXW_UINT16_NETWORK(y_density);
-
-            if (units == 1) {
-                x_dpi = x_density;
-                y_dpi = y_density;
-            }
-
-            if (units == 2) {
-                x_dpi = x_density * 2.54;
-                y_dpi = y_density * 2.54;
-            }
-
-            offset -= 12;
-        }
-
-        if (marker == 0xFFDA)
-            break;
-
-        if (!feof(stream)) {
-            fseek_err = fseek(stream, offset, SEEK_CUR);
-            if (fseek_err)
-                goto file_error;
-        }
-    }
-
-    /* Ensure that we read some valid data from the file. */
-    if (width == 0)
-        goto file_error;
-
-    /* Set the image metadata. */
-    image_options->image_type = LXW_IMAGE_JPEG;
-    image_options->width = width;
-    image_options->height = height;
-    image_options->x_dpi = x_dpi ? x_dpi : 96;
-    image_options->y_dpi = y_dpi ? x_dpi : 96;
-    image_options->extension = lxw_strdup("jpeg");
-
-    return LXW_NO_ERROR;
-
-file_error:
-    LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                     "no size data found in file: %s.",
-                     image_options->filename);
-
-    return LXW_ERROR_IMAGE_DIMENSIONS;
-}
-
-/*
- * Extract width and height information from a BMP file.
- */
-STATIC lxw_error
-_process_bmp(lxw_image_options *image_options)
-{
-    uint32_t width = 0;
-    uint32_t height = 0;
-    double x_dpi = 96;
-    double y_dpi = 96;
-    int fseek_err;
-
-    FILE *stream = image_options->stream;
-
-    /* Skip another 14 bytes to the start of the BMP height/width. */
-    fseek_err = fseek(stream, 14, SEEK_CUR);
-    if (fseek_err)
-        goto file_error;
-
-    if (fread(&width, sizeof(width), 1, stream) < 1)
-        width = 0;
-
-    if (fread(&height, sizeof(height), 1, stream) < 1)
-        height = 0;
-
-    /* Ensure that we read some valid data from the file. */
-    if (width == 0)
-        goto file_error;
-
-    height = LXW_UINT32_HOST(height);
-    width = LXW_UINT32_HOST(width);
-
-    /* Set the image metadata. */
-    image_options->image_type = LXW_IMAGE_BMP;
-    image_options->width = width;
-    image_options->height = height;
-    image_options->x_dpi = x_dpi;
-    image_options->y_dpi = y_dpi;
-    image_options->extension = lxw_strdup("bmp");
-
-    return LXW_NO_ERROR;
-
-file_error:
-    LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                     "no size data found in file: %s.",
-                     image_options->filename);
-
-    return LXW_ERROR_IMAGE_DIMENSIONS;
-}
-
-/*
- * Extract information from the image file such as dimension, type, filename,
- * and extension.
- */
-STATIC lxw_error
-_get_image_properties(lxw_image_options *image_options)
-{
-    unsigned char signature[4];
-
-    /* Read 4 bytes to look for the file header/signature. */
-    if (fread(signature, 1, 4, image_options->stream) < 4) {
-        LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                         "couldn't read file type for file: %s.",
-                         image_options->filename);
-        return LXW_ERROR_IMAGE_DIMENSIONS;
-    }
-
-    if (memcmp(&signature[1], "PNG", 3) == 0) {
-        if (_process_png(image_options) != LXW_NO_ERROR)
-            return LXW_ERROR_IMAGE_DIMENSIONS;
-    }
-    else if (signature[0] == 0xFF && signature[1] == 0xD8) {
-        if (_process_jpeg(image_options) != LXW_NO_ERROR)
-            return LXW_ERROR_IMAGE_DIMENSIONS;
-    }
-    else if (memcmp(signature, "BM", 2) == 0) {
-        if (_process_bmp(image_options) != LXW_NO_ERROR)
-            return LXW_ERROR_IMAGE_DIMENSIONS;
-    }
-    else {
-        LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                         "unsupported image format for file: %s.",
-                         image_options->filename);
-        return LXW_ERROR_IMAGE_DIMENSIONS;
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*****************************************************************************
- *
- * XML file assembly functions.
- *
- ****************************************************************************/
-
-/*
- * Write out a number worksheet cell. Doesn't use the xml functions as an
- * optimization in the inner cell writing loop.
- */
-STATIC void
-_write_number_cell(lxw_worksheet *self, char *range,
-                   int32_t style_index, lxw_cell *cell)
-{
-#ifdef USE_DOUBLE_FUNCTION
-    char data[LXW_ATTR_32];
-
-    lxw_sprintf_dbl(data, cell->u.number);
-
-    if (style_index)
-        fprintf(self->file,
-                "<c r=\"%s\" s=\"%d\"><v>%s</v></c>",
-                range, style_index, data);
-    else
-        fprintf(self->file, "<c r=\"%s\"><v>%s</v></c>", range, data);
-#else
-    if (style_index)
-        fprintf(self->file,
-                "<c r=\"%s\" s=\"%d\"><v>%.16g</v></c>",
-                range, style_index, cell->u.number);
-    else
-        fprintf(self->file,
-                "<c r=\"%s\"><v>%.16g</v></c>", range, cell->u.number);
-
-#endif
-}
-
-/*
- * Write out a string worksheet cell. Doesn't use the xml functions as an
- * optimization in the inner cell writing loop.
- */
-STATIC void
-_write_string_cell(lxw_worksheet *self, char *range,
-                   int32_t style_index, lxw_cell *cell)
-{
-
-    if (style_index)
-        fprintf(self->file,
-                "<c r=\"%s\" s=\"%d\" t=\"s\"><v>%d</v></c>",
-                range, style_index, cell->u.string_id);
-    else
-        fprintf(self->file,
-                "<c r=\"%s\" t=\"s\"><v>%d</v></c>",
-                range, cell->u.string_id);
-}
-
-/*
- * Write out an inline string. Doesn't use the xml functions as an
- * optimization in the inner cell writing loop.
- */
-STATIC void
-_write_inline_string_cell(lxw_worksheet *self, char *range,
-                          int32_t style_index, lxw_cell *cell)
-{
-    char *string = lxw_escape_data(cell->u.string);
-
-    /* Add attribute to preserve leading or trailing whitespace. */
-    if (isspace((unsigned char) string[0])
-        || isspace((unsigned char) string[strlen(string) - 1])) {
-
-        if (style_index)
-            fprintf(self->file,
-                    "<c r=\"%s\" s=\"%d\" t=\"inlineStr\"><is>"
-                    "<t xml:space=\"preserve\">%s</t></is></c>",
-                    range, style_index, string);
-        else
-            fprintf(self->file,
-                    "<c r=\"%s\" t=\"inlineStr\"><is>"
-                    "<t xml:space=\"preserve\">%s</t></is></c>",
-                    range, string);
-    }
-    else {
-        if (style_index)
-            fprintf(self->file,
-                    "<c r=\"%s\" s=\"%d\" t=\"inlineStr\">"
-                    "<is><t>%s</t></is></c>", range, style_index, string);
-        else
-            fprintf(self->file,
-                    "<c r=\"%s\" t=\"inlineStr\">"
-                    "<is><t>%s</t></is></c>", range, string);
-    }
-
-    free(string);
-}
-
-/*
- * Write out a formula worksheet cell with a numeric result.
- */
-STATIC void
-_write_formula_num_cell(lxw_worksheet *self, lxw_cell *cell)
-{
-    char data[LXW_ATTR_32];
-
-    lxw_sprintf_dbl(data, cell->formula_result);
-    lxw_xml_data_element(self->file, "f", cell->u.string, NULL);
-    lxw_xml_data_element(self->file, "v", data, NULL);
-}
-
-/*
- * Write out an array formula worksheet cell with a numeric result.
- */
-STATIC void
-_write_array_formula_num_cell(lxw_worksheet *self, lxw_cell *cell)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char data[LXW_ATTR_32];
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("t", "array");
-    LXW_PUSH_ATTRIBUTES_STR("ref", cell->user_data1);
-
-    lxw_sprintf_dbl(data, cell->formula_result);
-
-    lxw_xml_data_element(self->file, "f", cell->u.string, &attributes);
-    lxw_xml_data_element(self->file, "v", data, NULL);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write out a boolean worksheet cell.
- */
-STATIC void
-_write_boolean_cell(lxw_worksheet *self, lxw_cell *cell)
-{
-    char data[LXW_ATTR_32];
-
-    if (cell->u.number)
-        data[0] = '1';
-    else
-        data[0] = '0';
-
-    data[1] = '\0';
-
-    lxw_xml_data_element(self->file, "v", data, NULL);
-}
-
-/*
- * Calculate the "spans" attribute of the <row> tag. This is an XLSX
- * optimization and isn't strictly required. However, it makes comparing
- * files easier.
- *
- * The span is the same for each block of 16 rows.
- */
-STATIC void
-_calculate_spans(struct lxw_row *row, char *span, int32_t *block_num)
-{
-    lxw_cell *cell_min = RB_MIN(lxw_table_cells, row->cells);
-    lxw_cell *cell_max = RB_MAX(lxw_table_cells, row->cells);
-    lxw_col_t span_col_min = cell_min->col_num;
-    lxw_col_t span_col_max = cell_max->col_num;
-    lxw_col_t col_min;
-    lxw_col_t col_max;
-    *block_num = row->row_num / 16;
-
-    row = RB_NEXT(lxw_table_rows, root, row);
-
-    while (row && (int32_t) (row->row_num / 16) == *block_num) {
-
-        if (!RB_EMPTY(row->cells)) {
-            cell_min = RB_MIN(lxw_table_cells, row->cells);
-            cell_max = RB_MAX(lxw_table_cells, row->cells);
-            col_min = cell_min->col_num;
-            col_max = cell_max->col_num;
-
-            if (col_min < span_col_min)
-                span_col_min = col_min;
-
-            if (col_max > span_col_max)
-                span_col_max = col_max;
-        }
-
-        row = RB_NEXT(lxw_table_rows, root, row);
-    }
-
-    lxw_snprintf(span, LXW_MAX_CELL_RANGE_LENGTH,
-                 "%d:%d", span_col_min + 1, span_col_max + 1);
-}
-
-/*
- * Write out a generic worksheet cell.
- */
-STATIC void
-_write_cell(lxw_worksheet *self, lxw_cell *cell, lxw_format *row_format)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char range[LXW_MAX_CELL_NAME_LENGTH] = { 0 };
-    lxw_row_t row_num = cell->row_num;
-    lxw_col_t col_num = cell->col_num;
-    int32_t style_index = 0;
-
-    lxw_rowcol_to_cell(range, row_num, col_num);
-
-    if (cell->format) {
-        style_index = lxw_format_get_xf_index(cell->format);
-    }
-    else if (row_format) {
-        style_index = lxw_format_get_xf_index(row_format);
-    }
-    else if (col_num < self->col_formats_max && self->col_formats[col_num]) {
-        style_index = lxw_format_get_xf_index(self->col_formats[col_num]);
-    }
-
-    /* Unrolled optimization for most commonly written cell types. */
-    if (cell->type == NUMBER_CELL) {
-        _write_number_cell(self, range, style_index, cell);
-        return;
-    }
-
-    if (cell->type == STRING_CELL) {
-        _write_string_cell(self, range, style_index, cell);
-        return;
-    }
-
-    if (cell->type == INLINE_STRING_CELL) {
-        _write_inline_string_cell(self, range, style_index, cell);
-        return;
-    }
-
-    /* For other cell types use the general functions. */
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("r", range);
-
-    if (style_index)
-        LXW_PUSH_ATTRIBUTES_INT("s", style_index);
-
-    if (cell->type == FORMULA_CELL) {
-        lxw_xml_start_tag(self->file, "c", &attributes);
-        _write_formula_num_cell(self, cell);
-        lxw_xml_end_tag(self->file, "c");
-    }
-    else if (cell->type == BLANK_CELL) {
-        lxw_xml_empty_tag(self->file, "c", &attributes);
-    }
-    else if (cell->type == BOOLEAN_CELL) {
-        LXW_PUSH_ATTRIBUTES_STR("t", "b");
-        lxw_xml_start_tag(self->file, "c", &attributes);
-        _write_boolean_cell(self, cell);
-        lxw_xml_end_tag(self->file, "c");
-    }
-    else if (cell->type == ARRAY_FORMULA_CELL) {
-        lxw_xml_start_tag(self->file, "c", &attributes);
-        _write_array_formula_num_cell(self, cell);
-        lxw_xml_end_tag(self->file, "c");
-    }
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write out the worksheet data as a series of rows and cells.
- */
-STATIC void
-_worksheet_write_rows(lxw_worksheet *self)
-{
-    lxw_row *row;
-    lxw_cell *cell;
-    int32_t block_num = -1;
-    char spans[LXW_MAX_CELL_RANGE_LENGTH] = { 0 };
-
-    RB_FOREACH(row, lxw_table_rows, self->table) {
-
-        if (RB_EMPTY(row->cells)) {
-            /* Row contains no cells but has height, format or other data. */
-
-            /* Write a default span for default rows. */
-            if (self->default_row_set)
-                _write_row(self, row, "1:1");
-            else
-                _write_row(self, row, NULL);
-        }
-        else {
-            /* Row and cell data. */
-            if ((int32_t) row->row_num / 16 > block_num)
-                _calculate_spans(row, spans, &block_num);
-
-            _write_row(self, row, spans);
-
-            RB_FOREACH(cell, lxw_table_cells, row->cells) {
-                _write_cell(self, cell, row->format);
-            }
-            lxw_xml_end_tag(self->file, "row");
-        }
-    }
-}
-
-/*
- * Write out the worksheet data as a single row with cells. This method is
- * used when memory optimization is on. A single row is written and the data
- * array is reset. That way only one row of data is kept in memory at any one
- * time. We don't write span data in the optimized case since it is optional.
- */
-void
-lxw_worksheet_write_single_row(lxw_worksheet *self)
-{
-    lxw_row *row = self->optimize_row;
-    lxw_col_t col;
-
-    /* skip row if it doesn't contain row formatting, cell data or a comment. */
-    if (!(row->row_changed || row->data_changed))
-        return;
-
-    /* Write the cells if the row contains data. */
-    if (!row->data_changed) {
-        /* Row data only. No cells. */
-        _write_row(self, row, NULL);
-    }
-    else {
-        /* Row and cell data. */
-        _write_row(self, row, NULL);
-
-        for (col = self->dim_colmin; col <= self->dim_colmax; col++) {
-            if (self->array[col]) {
-                _write_cell(self, self->array[col], row->format);
-                _free_cell(self->array[col]);
-                self->array[col] = NULL;
-            }
-        }
-
-        lxw_xml_end_tag(self->file, "row");
-    }
-
-    /* Reset the row. */
-    row->height = LXW_DEF_ROW_HEIGHT;
-    row->format = NULL;
-    row->hidden = LXW_FALSE;
-    row->level = 0;
-    row->collapsed = LXW_FALSE;
-    row->data_changed = LXW_FALSE;
-    row->row_changed = LXW_FALSE;
-}
-
-/*
- * Write the <col> element.
- */
-STATIC void
-_worksheet_write_col_info(lxw_worksheet *self, lxw_col_options *options)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    double width = options->width;
-    uint8_t has_custom_width = LXW_TRUE;
-    int32_t xf_index = 0;
-    double max_digit_width = 7.0;       /* For Calabri 11. */
-    double padding = 5.0;
-
-    /* Get the format index. */
-    if (options->format) {
-        xf_index = lxw_format_get_xf_index(options->format);
-    }
-
-    /* Check if width is the Excel default. */
-    if (width == LXW_DEF_COL_WIDTH) {
-
-        /* The default col width changes to 0 for hidden columns. */
-        if (options->hidden)
-            width = 0;
-        else
-            has_custom_width = LXW_FALSE;
-
-    }
-
-    /* Convert column width from user units to character width. */
-    if (width > 0) {
-        if (width < 1) {
-            width = (uint16_t) (((uint16_t)
-                                 (width * (max_digit_width + padding) + 0.5))
-                                / max_digit_width * 256.0) / 256.0;
-        }
-        else {
-            width = (uint16_t) (((uint16_t)
-                                 (width * max_digit_width + 0.5) + padding)
-                                / max_digit_width * 256.0) / 256.0;
-        }
-    }
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("min", 1 + options->firstcol);
-    LXW_PUSH_ATTRIBUTES_INT("max", 1 + options->lastcol);
-    LXW_PUSH_ATTRIBUTES_DBL("width", width);
-
-    if (xf_index)
-        LXW_PUSH_ATTRIBUTES_INT("style", xf_index);
-
-    if (options->hidden)
-        LXW_PUSH_ATTRIBUTES_STR("hidden", "1");
-
-    if (has_custom_width)
-        LXW_PUSH_ATTRIBUTES_STR("customWidth", "1");
-
-    if (options->level)
-        LXW_PUSH_ATTRIBUTES_INT("outlineLevel", options->level);
-
-    if (options->collapsed)
-        LXW_PUSH_ATTRIBUTES_STR("collapsed", "1");
-
-    lxw_xml_empty_tag(self->file, "col", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <cols> element and <col> sub elements.
- */
-STATIC void
-_worksheet_write_cols(lxw_worksheet *self)
-{
-    lxw_col_t col;
-
-    if (!self->col_size_changed)
-        return;
-
-    lxw_xml_start_tag(self->file, "cols", NULL);
-
-    for (col = 0; col < self->col_options_max; col++) {
-        if (self->col_options[col])
-            _worksheet_write_col_info(self, self->col_options[col]);
-    }
-
-    lxw_xml_end_tag(self->file, "cols");
-}
-
-/*
- * Write the <mergeCell> element.
- */
-STATIC void
-_worksheet_write_merge_cell(lxw_worksheet *self,
-                            lxw_merged_range *merged_range)
-{
-
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char ref[LXW_MAX_CELL_RANGE_LENGTH];
-
-    LXW_INIT_ATTRIBUTES();
-
-    /* Convert the merge dimensions to a cell range. */
-    lxw_rowcol_to_range(ref, merged_range->first_row, merged_range->first_col,
-                        merged_range->last_row, merged_range->last_col);
-
-    LXW_PUSH_ATTRIBUTES_STR("ref", ref);
-
-    lxw_xml_empty_tag(self->file, "mergeCell", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <mergeCells> element.
- */
-STATIC void
-_worksheet_write_merge_cells(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_merged_range *merged_range;
-
-    if (self->merged_range_count) {
-        LXW_INIT_ATTRIBUTES();
-
-        LXW_PUSH_ATTRIBUTES_INT("count", self->merged_range_count);
-
-        lxw_xml_start_tag(self->file, "mergeCells", &attributes);
-
-        STAILQ_FOREACH(merged_range, self->merged_ranges, list_pointers) {
-            _worksheet_write_merge_cell(self, merged_range);
-        }
-        lxw_xml_end_tag(self->file, "mergeCells");
-
-        LXW_FREE_ATTRIBUTES();
-    }
-}
-
-/*
- * Write the <oddHeader> element.
- */
-STATIC void
-_worksheet_write_odd_header(lxw_worksheet *self)
-{
-    lxw_xml_data_element(self->file, "oddHeader", self->header, NULL);
-}
-
-/*
- * Write the <oddFooter> element.
- */
-STATIC void
-_worksheet_write_odd_footer(lxw_worksheet *self)
-{
-    lxw_xml_data_element(self->file, "oddFooter", self->footer, NULL);
-}
-
-/*
- * Write the <headerFooter> element.
- */
-STATIC void
-_worksheet_write_header_footer(lxw_worksheet *self)
-{
-    if (!self->header_footer_changed)
-        return;
-
-    lxw_xml_start_tag(self->file, "headerFooter", NULL);
-
-    if (self->header[0] != '\0')
-        _worksheet_write_odd_header(self);
-
-    if (self->footer[0] != '\0')
-        _worksheet_write_odd_footer(self);
-
-    lxw_xml_end_tag(self->file, "headerFooter");
-}
-
-/*
- * Write the <pageSetUpPr> element.
- */
-STATIC void
-_worksheet_write_page_set_up_pr(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!self->fit_page)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("fitToPage", "1");
-
-    lxw_xml_empty_tag(self->file, "pageSetUpPr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-
-}
-
-/*
- * Write the <tabColor> element.
- */
-STATIC void
-_worksheet_write_tab_color(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char rgb_str[LXW_ATTR_32];
-
-    if (self->tab_color == LXW_COLOR_UNSET)
-        return;
-
-    lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X",
-                 self->tab_color & LXW_COLOR_MASK);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
-
-    lxw_xml_empty_tag(self->file, "tabColor", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <outlinePr> element.
- */
-STATIC void
-_worksheet_write_outline_pr(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!self->outline_changed)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (self->outline_style)
-        LXW_PUSH_ATTRIBUTES_STR("applyStyles", "1");
-
-    if (!self->outline_below)
-        LXW_PUSH_ATTRIBUTES_STR("summaryBelow", "0");
-
-    if (!self->outline_right)
-        LXW_PUSH_ATTRIBUTES_STR("summaryRight", "0");
-
-    if (!self->outline_on)
-        LXW_PUSH_ATTRIBUTES_STR("showOutlineSymbols", "0");
-
-    lxw_xml_empty_tag(self->file, "outlinePr", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <sheetPr> element for Sheet level properties.
- */
-STATIC void
-_worksheet_write_sheet_pr(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    if (!self->fit_page
-        && !self->filter_on
-        && self->tab_color == LXW_COLOR_UNSET
-        && !self->outline_changed && !self->vba_codename) {
-        return;
-    }
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (self->vba_codename)
-        LXW_PUSH_ATTRIBUTES_INT("codeName", self->vba_codename);
-
-    if (self->filter_on)
-        LXW_PUSH_ATTRIBUTES_STR("filterMode", "1");
-
-    if (self->fit_page || self->tab_color != LXW_COLOR_UNSET
-        || self->outline_changed) {
-        lxw_xml_start_tag(self->file, "sheetPr", &attributes);
-        _worksheet_write_tab_color(self);
-        _worksheet_write_outline_pr(self);
-        _worksheet_write_page_set_up_pr(self);
-        lxw_xml_end_tag(self->file, "sheetPr");
-    }
-    else {
-        lxw_xml_empty_tag(self->file, "sheetPr", &attributes);
-    }
-
-    LXW_FREE_ATTRIBUTES();
-
-}
-
-/*
- * Write the <brk> element.
- */
-STATIC void
-_worksheet_write_brk(lxw_worksheet *self, uint32_t id, uint32_t max)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("id", id);
-    LXW_PUSH_ATTRIBUTES_INT("max", max);
-    LXW_PUSH_ATTRIBUTES_STR("man", "1");
-
-    lxw_xml_empty_tag(self->file, "brk", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <rowBreaks> element.
- */
-STATIC void
-_worksheet_write_row_breaks(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint16_t count = self->hbreaks_count;
-    uint16_t i;
-
-    if (!count)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", count);
-    LXW_PUSH_ATTRIBUTES_INT("manualBreakCount", count);
-
-    lxw_xml_start_tag(self->file, "rowBreaks", &attributes);
-
-    for (i = 0; i < count; i++)
-        _worksheet_write_brk(self, self->hbreaks[i], LXW_COL_MAX - 1);
-
-    lxw_xml_end_tag(self->file, "rowBreaks");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <colBreaks> element.
- */
-STATIC void
-_worksheet_write_col_breaks(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint16_t count = self->vbreaks_count;
-    uint16_t i;
-
-    if (!count)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", count);
-    LXW_PUSH_ATTRIBUTES_INT("manualBreakCount", count);
-
-    lxw_xml_start_tag(self->file, "colBreaks", &attributes);
-
-    for (i = 0; i < count; i++)
-        _worksheet_write_brk(self, self->vbreaks[i], LXW_ROW_MAX - 1);
-
-    lxw_xml_end_tag(self->file, "colBreaks");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <autoFilter> element.
- */
-STATIC void
-_worksheet_write_auto_filter(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char range[LXW_MAX_CELL_RANGE_LENGTH];
-
-    if (!self->autofilter.in_use)
-        return;
-
-    lxw_rowcol_to_range(range,
-                        self->autofilter.first_row,
-                        self->autofilter.first_col,
-                        self->autofilter.last_row, self->autofilter.last_col);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("ref", range);
-
-    lxw_xml_empty_tag(self->file, "autoFilter", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <hyperlink> element for external links.
- */
-STATIC void
-_worksheet_write_hyperlink_external(lxw_worksheet *self, lxw_row_t row_num,
-                                    lxw_col_t col_num, const char *location,
-                                    const char *tooltip, uint16_t id)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char ref[LXW_MAX_CELL_NAME_LENGTH];
-    char r_id[LXW_MAX_ATTRIBUTE_LENGTH];
-
-    lxw_rowcol_to_cell(ref, row_num, col_num);
-
-    lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", id);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("ref", ref);
-    LXW_PUSH_ATTRIBUTES_STR("r:id", r_id);
-
-    if (location)
-        LXW_PUSH_ATTRIBUTES_STR("location", location);
-
-    if (tooltip)
-        LXW_PUSH_ATTRIBUTES_STR("tooltip", tooltip);
-
-    lxw_xml_empty_tag(self->file, "hyperlink", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <hyperlink> element for internal links.
- */
-STATIC void
-_worksheet_write_hyperlink_internal(lxw_worksheet *self, lxw_row_t row_num,
-                                    lxw_col_t col_num, const char *location,
-                                    const char *display, const char *tooltip)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char ref[LXW_MAX_CELL_NAME_LENGTH];
-
-    lxw_rowcol_to_cell(ref, row_num, col_num);
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_STR("ref", ref);
-
-    if (location)
-        LXW_PUSH_ATTRIBUTES_STR("location", location);
-
-    if (tooltip)
-        LXW_PUSH_ATTRIBUTES_STR("tooltip", tooltip);
-
-    if (display)
-        LXW_PUSH_ATTRIBUTES_STR("display", display);
-
-    lxw_xml_empty_tag(self->file, "hyperlink", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Process any stored hyperlinks in row/col order and write the <hyperlinks>
- * element. The attributes are different for internal and external links.
- */
-STATIC void
-_worksheet_write_hyperlinks(lxw_worksheet *self)
-{
-
-    lxw_row *row;
-    lxw_cell *link;
-    lxw_rel_tuple *relationship;
-
-    if (RB_EMPTY(self->hyperlinks))
-        return;
-
-    /* Write the hyperlink elements. */
-    lxw_xml_start_tag(self->file, "hyperlinks", NULL);
-
-    RB_FOREACH(row, lxw_table_rows, self->hyperlinks) {
-
-        RB_FOREACH(link, lxw_table_cells, row->cells) {
-
-            if (link->type == HYPERLINK_URL
-                || link->type == HYPERLINK_EXTERNAL) {
-
-                self->rel_count++;
-
-                relationship = calloc(1, sizeof(lxw_rel_tuple));
-                GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
-
-                relationship->type = lxw_strdup("/hyperlink");
-                GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
-
-                relationship->target = lxw_strdup(link->u.string);
-                GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
-
-                relationship->target_mode = lxw_strdup("External");
-                GOTO_LABEL_ON_MEM_ERROR(relationship->target_mode, mem_error);
-
-                STAILQ_INSERT_TAIL(self->external_hyperlinks, relationship,
-                                   list_pointers);
-
-                _worksheet_write_hyperlink_external(self, link->row_num,
-                                                    link->col_num,
-                                                    link->user_data1,
-                                                    link->user_data2,
-                                                    self->rel_count);
-            }
-
-            if (link->type == HYPERLINK_INTERNAL) {
-
-                _worksheet_write_hyperlink_internal(self, link->row_num,
-                                                    link->col_num,
-                                                    link->u.string,
-                                                    link->user_data1,
-                                                    link->user_data2);
-            }
-
-        }
-
-    }
-
-    lxw_xml_end_tag(self->file, "hyperlinks");
-    return;
-
-mem_error:
-    if (relationship) {
-        free(relationship->type);
-        free(relationship->target);
-        free(relationship->target_mode);
-        free(relationship);
-    }
-    lxw_xml_end_tag(self->file, "hyperlinks");
-}
-
-/*
- * Write the <sheetProtection> element.
- */
-STATIC void
-_worksheet_write_sheet_protection(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-
-    struct lxw_protection *protect = &self->protection;
-
-    if (!protect->is_configured)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-
-    if (*protect->hash)
-        LXW_PUSH_ATTRIBUTES_STR("password", protect->hash);
-
-    if (!protect->no_sheet)
-        LXW_PUSH_ATTRIBUTES_INT("sheet", 1);
-
-    if (protect->content)
-        LXW_PUSH_ATTRIBUTES_INT("content", 1);
-
-    if (!protect->objects)
-        LXW_PUSH_ATTRIBUTES_INT("objects", 1);
-
-    if (!protect->scenarios)
-        LXW_PUSH_ATTRIBUTES_INT("scenarios", 1);
-
-    if (protect->format_cells)
-        LXW_PUSH_ATTRIBUTES_INT("formatCells", 0);
-
-    if (protect->format_columns)
-        LXW_PUSH_ATTRIBUTES_INT("formatColumns", 0);
-
-    if (protect->format_rows)
-        LXW_PUSH_ATTRIBUTES_INT("formatRows", 0);
-
-    if (protect->insert_columns)
-        LXW_PUSH_ATTRIBUTES_INT("insertColumns", 0);
-
-    if (protect->insert_rows)
-        LXW_PUSH_ATTRIBUTES_INT("insertRows", 0);
-
-    if (protect->insert_hyperlinks)
-        LXW_PUSH_ATTRIBUTES_INT("insertHyperlinks", 0);
-
-    if (protect->delete_columns)
-        LXW_PUSH_ATTRIBUTES_INT("deleteColumns", 0);
-
-    if (protect->delete_rows)
-        LXW_PUSH_ATTRIBUTES_INT("deleteRows", 0);
-
-    if (protect->no_select_locked_cells)
-        LXW_PUSH_ATTRIBUTES_INT("selectLockedCells", 1);
-
-    if (protect->sort)
-        LXW_PUSH_ATTRIBUTES_INT("sort", 0);
-
-    if (protect->autofilter)
-        LXW_PUSH_ATTRIBUTES_INT("autoFilter", 0);
-
-    if (protect->pivot_tables)
-        LXW_PUSH_ATTRIBUTES_INT("pivotTables", 0);
-
-    if (protect->no_select_unlocked_cells)
-        LXW_PUSH_ATTRIBUTES_INT("selectUnlockedCells", 1);
-
-    lxw_xml_empty_tag(self->file, "sheetProtection", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <drawing> element.
- */
-STATIC void
-_write_drawing(lxw_worksheet *self, uint16_t id)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    char r_id[LXW_MAX_ATTRIBUTE_LENGTH];
-
-    lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", id);
-
-    LXW_INIT_ATTRIBUTES();
-
-    LXW_PUSH_ATTRIBUTES_STR("r:id", r_id);
-
-    lxw_xml_empty_tag(self->file, "drawing", &attributes);
-
-    LXW_FREE_ATTRIBUTES();
-
-}
-
-/*
- * Write the <drawing> elements.
- */
-STATIC void
-_write_drawings(lxw_worksheet *self)
-{
-    if (!self->drawing)
-        return;
-
-    self->rel_count++;
-
-    _write_drawing(self, self->rel_count);
-}
-
-/*
- * Write the <formula1> element for numbers.
- */
-STATIC void
-_worksheet_write_formula1_num(lxw_worksheet *self, double number)
-{
-    char data[LXW_ATTR_32];
-
-    lxw_sprintf_dbl(data, number);
-
-    lxw_xml_data_element(self->file, "formula1", data, NULL);
-}
-
-/*
- * Write the <formula1> element for strings/formulas.
- */
-STATIC void
-_worksheet_write_formula1_str(lxw_worksheet *self, char *str)
-{
-    lxw_xml_data_element(self->file, "formula1", str, NULL);
-}
-
-/*
- * Write the <formula2> element for numbers.
- */
-STATIC void
-_worksheet_write_formula2_num(lxw_worksheet *self, double number)
-{
-    char data[LXW_ATTR_32];
-
-    lxw_sprintf_dbl(data, number);
-
-    lxw_xml_data_element(self->file, "formula2", data, NULL);
-}
-
-/*
- * Write the <formula2> element for strings/formulas.
- */
-STATIC void
-_worksheet_write_formula2_str(lxw_worksheet *self, char *str)
-{
-    lxw_xml_data_element(self->file, "formula2", str, NULL);
-}
-
-/*
- * Write the <dataValidation> element.
- */
-STATIC void
-_worksheet_write_data_validation(lxw_worksheet *self,
-                                 lxw_data_validation *validation)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    uint8_t is_between = 0;
-
-    LXW_INIT_ATTRIBUTES();
-
-    switch (validation->validate) {
-        case LXW_VALIDATION_TYPE_INTEGER:
-        case LXW_VALIDATION_TYPE_INTEGER_FORMULA:
-            LXW_PUSH_ATTRIBUTES_STR("type", "whole");
-            break;
-        case LXW_VALIDATION_TYPE_DECIMAL:
-        case LXW_VALIDATION_TYPE_DECIMAL_FORMULA:
-            LXW_PUSH_ATTRIBUTES_STR("type", "decimal");
-            break;
-        case LXW_VALIDATION_TYPE_LIST:
-        case LXW_VALIDATION_TYPE_LIST_FORMULA:
-            LXW_PUSH_ATTRIBUTES_STR("type", "list");
-            break;
-        case LXW_VALIDATION_TYPE_DATE:
-        case LXW_VALIDATION_TYPE_DATE_FORMULA:
-        case LXW_VALIDATION_TYPE_DATE_NUMBER:
-            LXW_PUSH_ATTRIBUTES_STR("type", "date");
-            break;
-        case LXW_VALIDATION_TYPE_TIME:
-        case LXW_VALIDATION_TYPE_TIME_FORMULA:
-        case LXW_VALIDATION_TYPE_TIME_NUMBER:
-            LXW_PUSH_ATTRIBUTES_STR("type", "time");
-            break;
-        case LXW_VALIDATION_TYPE_LENGTH:
-        case LXW_VALIDATION_TYPE_LENGTH_FORMULA:
-            LXW_PUSH_ATTRIBUTES_STR("type", "textLength");
-            break;
-        case LXW_VALIDATION_TYPE_CUSTOM_FORMULA:
-            LXW_PUSH_ATTRIBUTES_STR("type", "custom");
-            break;
-    }
-
-    switch (validation->criteria) {
-        case LXW_VALIDATION_CRITERIA_EQUAL_TO:
-            LXW_PUSH_ATTRIBUTES_STR("operator", "equal");
-            break;
-        case LXW_VALIDATION_CRITERIA_NOT_EQUAL_TO:
-            LXW_PUSH_ATTRIBUTES_STR("operator", "notEqual");
-            break;
-        case LXW_VALIDATION_CRITERIA_LESS_THAN:
-            LXW_PUSH_ATTRIBUTES_STR("operator", "lessThan");
-            break;
-        case LXW_VALIDATION_CRITERIA_LESS_THAN_OR_EQUAL_TO:
-            LXW_PUSH_ATTRIBUTES_STR("operator", "lessThanOrEqual");
-            break;
-        case LXW_VALIDATION_CRITERIA_GREATER_THAN:
-            LXW_PUSH_ATTRIBUTES_STR("operator", "greaterThan");
-            break;
-        case LXW_VALIDATION_CRITERIA_GREATER_THAN_OR_EQUAL_TO:
-            LXW_PUSH_ATTRIBUTES_STR("operator", "greaterThanOrEqual");
-            break;
-        case LXW_VALIDATION_CRITERIA_BETWEEN:
-            /* Between is the default for 2 formulas and isn't added. */
-            is_between = 1;
-            break;
-        case LXW_VALIDATION_CRITERIA_NOT_BETWEEN:
-            is_between = 1;
-            LXW_PUSH_ATTRIBUTES_STR("operator", "notBetween");
-            break;
-    }
-
-    if (validation->error_type == LXW_VALIDATION_ERROR_TYPE_WARNING)
-        LXW_PUSH_ATTRIBUTES_STR("errorStyle", "warning");
-
-    if (validation->error_type == LXW_VALIDATION_ERROR_TYPE_INFORMATION)
-        LXW_PUSH_ATTRIBUTES_STR("errorStyle", "information");
-
-    if (validation->ignore_blank)
-        LXW_PUSH_ATTRIBUTES_INT("allowBlank", 1);
-
-    if (validation->dropdown == LXW_VALIDATION_OFF)
-        LXW_PUSH_ATTRIBUTES_INT("showDropDown", 1);
-
-    if (validation->show_input)
-        LXW_PUSH_ATTRIBUTES_INT("showInputMessage", 1);
-
-    if (validation->show_error)
-        LXW_PUSH_ATTRIBUTES_INT("showErrorMessage", 1);
-
-    if (validation->error_title)
-        LXW_PUSH_ATTRIBUTES_STR("errorTitle", validation->error_title);
-
-    if (validation->error_message)
-        LXW_PUSH_ATTRIBUTES_STR("error", validation->error_message);
-
-    if (validation->input_title)
-        LXW_PUSH_ATTRIBUTES_STR("promptTitle", validation->input_title);
-
-    if (validation->input_message)
-        LXW_PUSH_ATTRIBUTES_STR("prompt", validation->input_message);
-
-    LXW_PUSH_ATTRIBUTES_STR("sqref", validation->sqref);
-
-    if (validation->validate == LXW_VALIDATION_TYPE_ANY)
-        lxw_xml_empty_tag(self->file, "dataValidation", &attributes);
-    else
-        lxw_xml_start_tag(self->file, "dataValidation", &attributes);
-
-    /* Write the formula1 and formula2 elements. */
-    switch (validation->validate) {
-        case LXW_VALIDATION_TYPE_INTEGER:
-        case LXW_VALIDATION_TYPE_DECIMAL:
-        case LXW_VALIDATION_TYPE_LENGTH:
-        case LXW_VALIDATION_TYPE_DATE:
-        case LXW_VALIDATION_TYPE_TIME:
-        case LXW_VALIDATION_TYPE_DATE_NUMBER:
-        case LXW_VALIDATION_TYPE_TIME_NUMBER:
-            _worksheet_write_formula1_num(self, validation->value_number);
-            if (is_between)
-                _worksheet_write_formula2_num(self,
-                                              validation->maximum_number);
-            break;
-        case LXW_VALIDATION_TYPE_INTEGER_FORMULA:
-        case LXW_VALIDATION_TYPE_DECIMAL_FORMULA:
-        case LXW_VALIDATION_TYPE_LENGTH_FORMULA:
-        case LXW_VALIDATION_TYPE_DATE_FORMULA:
-        case LXW_VALIDATION_TYPE_TIME_FORMULA:
-        case LXW_VALIDATION_TYPE_LIST:
-        case LXW_VALIDATION_TYPE_LIST_FORMULA:
-        case LXW_VALIDATION_TYPE_CUSTOM_FORMULA:
-            _worksheet_write_formula1_str(self, validation->value_formula);
-            if (is_between)
-                _worksheet_write_formula2_str(self,
-                                              validation->maximum_formula);
-            break;
-    }
-
-    if (validation->validate != LXW_VALIDATION_TYPE_ANY)
-        lxw_xml_end_tag(self->file, "dataValidation");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Write the <dataValidations> element.
- */
-STATIC void
-_worksheet_write_data_validations(lxw_worksheet *self)
-{
-    struct xml_attribute_list attributes;
-    struct xml_attribute *attribute;
-    lxw_data_validation *data_validation;
-
-    if (self->num_validations == 0)
-        return;
-
-    LXW_INIT_ATTRIBUTES();
-    LXW_PUSH_ATTRIBUTES_INT("count", self->num_validations);
-
-    lxw_xml_start_tag(self->file, "dataValidations", &attributes);
-
-    STAILQ_FOREACH(data_validation, self->data_validations, list_pointers) {
-        /* Write the dataValidation element. */
-        _worksheet_write_data_validation(self, data_validation);
-    }
-
-    lxw_xml_end_tag(self->file, "dataValidations");
-
-    LXW_FREE_ATTRIBUTES();
-}
-
-/*
- * Assemble and write the XML file.
- */
-void
-lxw_worksheet_assemble_xml_file(lxw_worksheet *self)
-{
-    /* Write the XML declaration. */
-    _worksheet_xml_declaration(self);
-
-    /* Write the worksheet element. */
-    _worksheet_write_worksheet(self);
-
-    /* Write the worksheet properties. */
-    _worksheet_write_sheet_pr(self);
-
-    /* Write the worksheet dimensions. */
-    _worksheet_write_dimension(self);
-
-    /* Write the sheet view properties. */
-    _worksheet_write_sheet_views(self);
-
-    /* Write the sheet format properties. */
-    _worksheet_write_sheet_format_pr(self);
-
-    /* Write the sheet column info. */
-    _worksheet_write_cols(self);
-
-    /* Write the sheetData element. */
-    if (!self->optimize)
-        _worksheet_write_sheet_data(self);
-    else
-        _worksheet_write_optimized_sheet_data(self);
-
-    /* Write the sheetProtection element. */
-    _worksheet_write_sheet_protection(self);
-
-    /* Write the autoFilter element. */
-    _worksheet_write_auto_filter(self);
-
-    /* Write the mergeCells element. */
-    _worksheet_write_merge_cells(self);
-
-    /* Write the dataValidations element. */
-    _worksheet_write_data_validations(self);
-
-    /* Write the hyperlink element. */
-    _worksheet_write_hyperlinks(self);
-
-    /* Write the printOptions element. */
-    _worksheet_write_print_options(self);
-
-    /* Write the worksheet page_margins. */
-    _worksheet_write_page_margins(self);
-
-    /* Write the worksheet page setup. */
-    _worksheet_write_page_setup(self);
-
-    /* Write the headerFooter element. */
-    _worksheet_write_header_footer(self);
-
-    /* Write the rowBreaks element. */
-    _worksheet_write_row_breaks(self);
-
-    /* Write the colBreaks element. */
-    _worksheet_write_col_breaks(self);
-
-    /* Write the drawing element. */
-    _write_drawings(self);
-
-    /* Close the worksheet tag. */
-    lxw_xml_end_tag(self->file, "worksheet");
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-/*
- * Write a number to a cell in Excel.
- */
-lxw_error
-worksheet_write_number(lxw_worksheet *self,
-                       lxw_row_t row_num,
-                       lxw_col_t col_num, double value, lxw_format *format)
-{
-    lxw_cell *cell;
-    lxw_error err;
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    cell = _new_number_cell(row_num, col_num, value, format);
-
-    _insert_cell(self, row_num, col_num, cell);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write a string to an Excel file.
- */
-lxw_error
-worksheet_write_string(lxw_worksheet *self,
-                       lxw_row_t row_num,
-                       lxw_col_t col_num, const char *string,
-                       lxw_format *format)
-{
-    lxw_cell *cell;
-    int32_t string_id;
-    char *string_copy;
-    struct sst_element *sst_element;
-    lxw_error err;
-
-    if (!string || !*string) {
-        /* Treat a NULL or empty string with formatting as a blank cell. */
-        /* Null strings without formats should be ignored.      */
-        if (format)
-            return worksheet_write_blank(self, row_num, col_num, format);
-        else
-            return LXW_NO_ERROR;
-    }
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    if (lxw_utf8_strlen(string) > LXW_STR_MAX)
-        return LXW_ERROR_MAX_STRING_LENGTH_EXCEEDED;
-
-    if (!self->optimize) {
-        /* Get the SST element and string id. */
-        sst_element = lxw_get_sst_index(self->sst, string);
-
-        if (!sst_element)
-            return LXW_ERROR_SHARED_STRING_INDEX_NOT_FOUND;
-
-        string_id = sst_element->index;
-        cell = _new_string_cell(row_num, col_num, string_id,
-                                sst_element->string, format);
-    }
-    else {
-        /* Look for and escape control chars in the string. */
-        if (strpbrk(string, "\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C"
-                    "\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"
-                    "\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) {
-            string_copy = lxw_escape_control_characters(string);
-        }
-        else {
-            string_copy = lxw_strdup(string);
-        }
-        cell = _new_inline_string_cell(row_num, col_num, string_copy, format);
-    }
-
-    _insert_cell(self, row_num, col_num, cell);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write a formula with a numerical result to a cell in Excel.
- */
-lxw_error
-worksheet_write_formula_num(lxw_worksheet *self,
-                            lxw_row_t row_num,
-                            lxw_col_t col_num,
-                            const char *formula,
-                            lxw_format *format, double result)
-{
-    lxw_cell *cell;
-    char *formula_copy;
-    lxw_error err;
-
-    if (!formula)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    /* Strip leading "=" from formula. */
-    if (formula[0] == '=')
-        formula_copy = lxw_strdup(formula + 1);
-    else
-        formula_copy = lxw_strdup(formula);
-
-    cell = _new_formula_cell(row_num, col_num, formula_copy, format);
-    cell->formula_result = result;
-
-    _insert_cell(self, row_num, col_num, cell);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write a formula with a default result to a cell in Excel .
- */
-lxw_error
-worksheet_write_formula(lxw_worksheet *self,
-                        lxw_row_t row_num,
-                        lxw_col_t col_num, const char *formula,
-                        lxw_format *format)
-{
-    return worksheet_write_formula_num(self, row_num, col_num, formula,
-                                       format, 0);
-}
-
-/*
- * Write a formula with a numerical result to a cell in Excel.
- */
-lxw_error
-worksheet_write_array_formula_num(lxw_worksheet *self,
-                                  lxw_row_t first_row,
-                                  lxw_col_t first_col,
-                                  lxw_row_t last_row,
-                                  lxw_col_t last_col,
-                                  const char *formula,
-                                  lxw_format *format, double result)
-{
-    lxw_cell *cell;
-    lxw_row_t tmp_row;
-    lxw_col_t tmp_col;
-    char *formula_copy;
-    char *range;
-    lxw_error err;
-
-    /* Swap last row/col with first row/col as necessary */
-    if (first_row > last_row) {
-        tmp_row = last_row;
-        last_row = first_row;
-        first_row = tmp_row;
-    }
-    if (first_col > last_col) {
-        tmp_col = last_col;
-        last_col = first_col;
-        first_col = tmp_col;
-    }
-
-    if (!formula)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    /* Check that column number is valid and store the max value */
-    err = _check_dimensions(self, last_row, last_col, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    /* Define the array range. */
-    range = calloc(1, LXW_MAX_CELL_RANGE_LENGTH);
-    RETURN_ON_MEM_ERROR(range, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    if (first_row == last_row && first_col == last_col)
-        lxw_rowcol_to_cell(range, first_row, last_col);
-    else
-        lxw_rowcol_to_range(range, first_row, first_col, last_row, last_col);
-
-    /* Copy and trip leading "{=" from formula. */
-    if (formula[0] == '{')
-        if (formula[1] == '=')
-            formula_copy = lxw_strdup(formula + 2);
-        else
-            formula_copy = lxw_strdup(formula + 1);
-    else
-        formula_copy = lxw_strdup(formula);
-
-    /* Strip trailing "}" from formula. */
-    if (formula_copy[strlen(formula_copy) - 1] == '}')
-        formula_copy[strlen(formula_copy) - 1] = '\0';
-
-    /* Create a new array formula cell object. */
-    cell = _new_array_formula_cell(first_row, first_col,
-                                   formula_copy, range, format);
-
-    cell->formula_result = result;
-
-    _insert_cell(self, first_row, first_col, cell);
-
-    /* Pad out the rest of the area with formatted zeroes. */
-    if (!self->optimize) {
-        for (tmp_row = first_row; tmp_row <= last_row; tmp_row++) {
-            for (tmp_col = first_col; tmp_col <= last_col; tmp_col++) {
-                if (tmp_row == first_row && tmp_col == first_col)
-                    continue;
-
-                worksheet_write_number(self, tmp_row, tmp_col, 0, format);
-            }
-        }
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write an array formula with a default result to a cell in Excel .
- */
-lxw_error
-worksheet_write_array_formula(lxw_worksheet *self,
-                              lxw_row_t first_row,
-                              lxw_col_t first_col,
-                              lxw_row_t last_row,
-                              lxw_col_t last_col,
-                              const char *formula, lxw_format *format)
-{
-    return worksheet_write_array_formula_num(self, first_row, first_col,
-                                             last_row, last_col, formula,
-                                             format, 0);
-}
-
-/*
- * Write a blank cell with a format to a cell in Excel.
- */
-lxw_error
-worksheet_write_blank(lxw_worksheet *self,
-                      lxw_row_t row_num, lxw_col_t col_num,
-                      lxw_format *format)
-{
-    lxw_cell *cell;
-    lxw_error err;
-
-    /* Blank cells without formatting are ignored by Excel. */
-    if (!format)
-        return LXW_NO_ERROR;
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    cell = _new_blank_cell(row_num, col_num, format);
-
-    _insert_cell(self, row_num, col_num, cell);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write a boolean cell with a format to a cell in Excel.
- */
-lxw_error
-worksheet_write_boolean(lxw_worksheet *self,
-                        lxw_row_t row_num, lxw_col_t col_num,
-                        int value, lxw_format *format)
-{
-    lxw_cell *cell;
-    lxw_error err;
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-
-    if (err)
-        return err;
-
-    cell = _new_boolean_cell(row_num, col_num, value, format);
-
-    _insert_cell(self, row_num, col_num, cell);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write a date and or time to a cell in Excel.
- */
-lxw_error
-worksheet_write_datetime(lxw_worksheet *self,
-                         lxw_row_t row_num,
-                         lxw_col_t col_num, lxw_datetime *datetime,
-                         lxw_format *format)
-{
-    lxw_cell *cell;
-    double excel_date;
-    lxw_error err;
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    excel_date = lxw_datetime_to_excel_date(datetime, LXW_EPOCH_1900);
-
-    cell = _new_number_cell(row_num, col_num, excel_date, format);
-
-    _insert_cell(self, row_num, col_num, cell);
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Write a hyperlink/url to an Excel file.
- */
-lxw_error
-worksheet_write_url_opt(lxw_worksheet *self,
-                        lxw_row_t row_num,
-                        lxw_col_t col_num, const char *url,
-                        lxw_format *format, const char *string,
-                        const char *tooltip)
-{
-    lxw_cell *link;
-    char *string_copy = NULL;
-    char *url_copy = NULL;
-    char *url_external = NULL;
-    char *url_string = NULL;
-    char *tooltip_copy = NULL;
-    char *found_string;
-    lxw_error err;
-    size_t string_size;
-    size_t i;
-    enum cell_types link_type = HYPERLINK_URL;
-
-    if (!url || !*url)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    /* Check the Excel limit of URLS per worksheet. */
-    if (self->hlink_count > LXW_MAX_NUMBER_URLS)
-        return LXW_ERROR_WORKSHEET_MAX_NUMBER_URLS_EXCEEDED;
-
-    err = _check_dimensions(self, row_num, col_num, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    /* Set the URI scheme from internal links. */
-    found_string = strstr(url, "internal:");
-    if (found_string)
-        link_type = HYPERLINK_INTERNAL;
-
-    /* Set the URI scheme from external links. */
-    found_string = strstr(url, "external:");
-    if (found_string)
-        link_type = HYPERLINK_EXTERNAL;
-
-    if (string) {
-        string_copy = lxw_strdup(string);
-        GOTO_LABEL_ON_MEM_ERROR(string_copy, mem_error);
-    }
-    else {
-        if (link_type == HYPERLINK_URL) {
-            /* Strip the mailto header. */
-            found_string = strstr(url, "mailto:");
-            if (found_string)
-                string_copy = lxw_strdup(url + sizeof("mailto"));
-            else
-                string_copy = lxw_strdup(url);
-        }
-        else {
-            string_copy = lxw_strdup(url + sizeof("__ternal"));
-        }
-        GOTO_LABEL_ON_MEM_ERROR(string_copy, mem_error);
-    }
-
-    if (url) {
-        if (link_type == HYPERLINK_URL)
-            url_copy = lxw_strdup(url);
-        else
-            url_copy = lxw_strdup(url + sizeof("__ternal"));
-
-        GOTO_LABEL_ON_MEM_ERROR(url_copy, mem_error);
-    }
-
-    if (tooltip) {
-        tooltip_copy = lxw_strdup(tooltip);
-        GOTO_LABEL_ON_MEM_ERROR(tooltip_copy, mem_error);
-    }
-
-    if (link_type == HYPERLINK_INTERNAL) {
-        url_string = lxw_strdup(string_copy);
-        GOTO_LABEL_ON_MEM_ERROR(url_string, mem_error);
-    }
-
-    /* Escape the URL. */
-    if (link_type == HYPERLINK_URL && strlen(url_copy) >= 3) {
-        uint8_t not_escaped = 1;
-
-        /* First check if the URL is already escaped by the user. */
-        for (i = 0; i <= strlen(url_copy) - 3; i++) {
-            if (url_copy[i] == '%' && isxdigit(url_copy[i + 1])
-                && isxdigit(url_copy[i + 2])) {
-
-                not_escaped = 0;
-                break;
-            }
-        }
-
-        if (not_escaped) {
-            url_external = calloc(1, strlen(url_copy) * 3 + 1);
-            GOTO_LABEL_ON_MEM_ERROR(url_external, mem_error);
-
-            for (i = 0; i <= strlen(url_copy); i++) {
-                switch (url_copy[i]) {
-                    case (' '):
-                    case ('"'):
-                    case ('%'):
-                    case ('<'):
-                    case ('>'):
-                    case ('['):
-                    case (']'):
-                    case ('`'):
-                    case ('^'):
-                    case ('{'):
-                    case ('}'):
-                        lxw_snprintf(url_external + strlen(url_external),
-                                     sizeof("%xx"), "%%%2x", url_copy[i]);
-                        break;
-                    default:
-                        url_external[strlen(url_external)] = url_copy[i];
-                }
-
-            }
-
-            free(url_copy);
-            url_copy = lxw_strdup(url_external);
-            GOTO_LABEL_ON_MEM_ERROR(url_copy, mem_error);
-
-            free(url_external);
-            url_external = NULL;
-        }
-    }
-
-    if (link_type == HYPERLINK_EXTERNAL) {
-        /* External Workbook links need to be modified into the right format.
-         * The URL will look something like "c:\temp\file.xlsx#Sheet!A1".
-         * We need the part to the left of the # as the URL and the part to
-         * the right as the "location" string (if it exists).
-         */
-
-        /* For external links change the dir separator from Unix to DOS. */
-        for (i = 0; i <= strlen(url_copy); i++)
-            if (url_copy[i] == '/')
-                url_copy[i] = '\\';
-
-        for (i = 0; i <= strlen(string_copy); i++)
-            if (string_copy[i] == '/')
-                string_copy[i] = '\\';
-
-        found_string = strchr(url_copy, '#');
-
-        if (found_string) {
-            url_string = lxw_strdup(found_string + 1);
-            GOTO_LABEL_ON_MEM_ERROR(url_string, mem_error);
-
-            *found_string = '\0';
-        }
-
-        /* Look for Windows style "C:/" link or Windows share "\\" link. */
-        found_string = strchr(url_copy, ':');
-        if (!found_string)
-            found_string = strstr(url_copy, "\\\\");
-
-        if (found_string) {
-            /* Add the file:/// URI to the url if non-local. */
-            string_size = sizeof("file:///") + strlen(url_copy);
-            url_external = calloc(1, string_size);
-            GOTO_LABEL_ON_MEM_ERROR(url_external, mem_error);
-
-            lxw_snprintf(url_external, string_size, "file:///%s", url_copy);
-
-        }
-
-        /* Convert a ./dir/file.xlsx link to dir/file.xlsx. */
-        found_string = strstr(url_copy, ".\\");
-        if (found_string == url_copy)
-            memmove(url_copy, url_copy + 2, strlen(url_copy) - 1);
-
-        if (url_external) {
-            free(url_copy);
-            url_copy = lxw_strdup(url_external);
-            GOTO_LABEL_ON_MEM_ERROR(url_copy, mem_error);
-
-            free(url_external);
-            url_external = NULL;
-        }
-
-    }
-
-    /* Excel limits escaped URL to 255 characters. */
-    if (lxw_utf8_strlen(url_copy) > 255)
-        goto mem_error;
-
-    err = worksheet_write_string(self, row_num, col_num, string_copy, format);
-    if (err)
-        goto mem_error;
-
-    link = _new_hyperlink_cell(row_num, col_num, link_type, url_copy,
-                               url_string, tooltip_copy);
-    GOTO_LABEL_ON_MEM_ERROR(link, mem_error);
-
-    _insert_hyperlink(self, row_num, col_num, link);
-
-    free(string_copy);
-    self->hlink_count++;
-    return LXW_NO_ERROR;
-
-mem_error:
-    free(string_copy);
-    free(url_copy);
-    free(url_external);
-    free(url_string);
-    free(tooltip_copy);
-    return LXW_ERROR_MEMORY_MALLOC_FAILED;
-}
-
-/*
- * Write a hyperlink/url to an Excel file.
- */
-lxw_error
-worksheet_write_url(lxw_worksheet *self,
-                    lxw_row_t row_num,
-                    lxw_col_t col_num, const char *url, lxw_format *format)
-{
-    return worksheet_write_url_opt(self, row_num, col_num, url, format, NULL,
-                                   NULL);
-}
-
-/*
- * Set the properties of a single column or a range of columns with options.
- */
-lxw_error
-worksheet_set_column_opt(lxw_worksheet *self,
-                         lxw_col_t firstcol,
-                         lxw_col_t lastcol,
-                         double width,
-                         lxw_format *format,
-                         lxw_row_col_options *user_options)
-{
-    lxw_col_options *copied_options;
-    uint8_t ignore_row = LXW_TRUE;
-    uint8_t ignore_col = LXW_TRUE;
-    uint8_t hidden = LXW_FALSE;
-    uint8_t level = 0;
-    uint8_t collapsed = LXW_FALSE;
-    lxw_col_t col;
-    lxw_error err;
-
-    if (user_options) {
-        hidden = user_options->hidden;
-        level = user_options->level;
-        collapsed = user_options->collapsed;
-    }
-
-    /* Ensure second col is larger than first. */
-    if (firstcol > lastcol) {
-        lxw_col_t tmp = firstcol;
-        firstcol = lastcol;
-        lastcol = tmp;
-    }
-
-    /* Ensure that the cols are valid and store max and min values.
-     * NOTE: The check shouldn't modify the row dimensions and should only
-     *       modify the column dimensions in certain cases. */
-    if (format != NULL || (width != LXW_DEF_COL_WIDTH && hidden))
-        ignore_col = LXW_FALSE;
-
-    err = _check_dimensions(self, 0, firstcol, ignore_row, ignore_col);
-
-    if (!err)
-        err = _check_dimensions(self, 0, lastcol, ignore_row, ignore_col);
-
-    if (err)
-        return err;
-
-    /* Resize the col_options array if required. */
-    if (firstcol >= self->col_options_max) {
-        lxw_col_t col;
-        lxw_col_t old_size = self->col_options_max;
-        lxw_col_t new_size = _next_power_of_two(firstcol + 1);
-        lxw_col_options **new_ptr = realloc(self->col_options,
-                                            new_size *
-                                            sizeof(lxw_col_options *));
-
-        if (new_ptr) {
-            for (col = old_size; col < new_size; col++)
-                new_ptr[col] = NULL;
-
-            self->col_options = new_ptr;
-            self->col_options_max = new_size;
-        }
-        else {
-            return LXW_ERROR_MEMORY_MALLOC_FAILED;
-        }
-    }
-
-    /* Resize the col_formats array if required. */
-    if (lastcol >= self->col_formats_max) {
-        lxw_col_t col;
-        lxw_col_t old_size = self->col_formats_max;
-        lxw_col_t new_size = _next_power_of_two(lastcol + 1);
-        lxw_format **new_ptr = realloc(self->col_formats,
-                                       new_size * sizeof(lxw_format *));
-
-        if (new_ptr) {
-            for (col = old_size; col < new_size; col++)
-                new_ptr[col] = NULL;
-
-            self->col_formats = new_ptr;
-            self->col_formats_max = new_size;
-        }
-        else {
-            return LXW_ERROR_MEMORY_MALLOC_FAILED;
-        }
-    }
-
-    /* Store the column options. */
-    copied_options = calloc(1, sizeof(lxw_col_options));
-    RETURN_ON_MEM_ERROR(copied_options, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    /* Ensure the level is <= 7). */
-    if (level > 7)
-        level = 7;
-
-    if (level > self->outline_col_level)
-        self->outline_col_level = level;
-
-    /* Set the column properties. */
-    copied_options->firstcol = firstcol;
-    copied_options->lastcol = lastcol;
-    copied_options->width = width;
-    copied_options->format = format;
-    copied_options->hidden = hidden;
-    copied_options->level = level;
-    copied_options->collapsed = collapsed;
-
-    self->col_options[firstcol] = copied_options;
-
-    /* Store the column formats for use when writing cell data. */
-    for (col = firstcol; col <= lastcol; col++) {
-        self->col_formats[col] = format;
-    }
-
-    /* Store the column change to allow optimizations. */
-    self->col_size_changed = LXW_TRUE;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the properties of a single column or a range of columns.
- */
-lxw_error
-worksheet_set_column(lxw_worksheet *self,
-                     lxw_col_t firstcol,
-                     lxw_col_t lastcol, double width, lxw_format *format)
-{
-    return worksheet_set_column_opt(self, firstcol, lastcol, width, format,
-                                    NULL);
-}
-
-/*
- * Set the properties of a row with options.
- */
-lxw_error
-worksheet_set_row_opt(lxw_worksheet *self,
-                      lxw_row_t row_num,
-                      double height,
-                      lxw_format *format, lxw_row_col_options *user_options)
-{
-
-    lxw_col_t min_col;
-    uint8_t hidden = LXW_FALSE;
-    uint8_t level = 0;
-    uint8_t collapsed = LXW_FALSE;
-    lxw_row *row;
-    lxw_error err;
-
-    if (user_options) {
-        hidden = user_options->hidden;
-        level = user_options->level;
-        collapsed = user_options->collapsed;
-    }
-
-    /* Use minimum col in _check_dimensions(). */
-    if (self->dim_colmin != LXW_COL_MAX)
-        min_col = self->dim_colmin;
-    else
-        min_col = 0;
-
-    err = _check_dimensions(self, row_num, min_col, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    /* If the height is 0 the row is hidden and the height is the default. */
-    if (height == 0) {
-        hidden = LXW_TRUE;
-        height = self->default_row_height;
-    }
-
-    /* Ensure the level is <= 7). */
-    if (level > 7)
-        level = 7;
-
-    if (level > self->outline_row_level)
-        self->outline_row_level = level;
-
-    /* Store the row properties. */
-    row = _get_row(self, row_num);
-
-    row->height = height;
-    row->format = format;
-    row->hidden = hidden;
-    row->level = level;
-    row->collapsed = collapsed;
-    row->row_changed = LXW_TRUE;
-
-    if (height != self->default_row_height)
-        row->height_changed = LXW_TRUE;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the properties of a row.
- */
-lxw_error
-worksheet_set_row(lxw_worksheet *self,
-                  lxw_row_t row_num, double height, lxw_format *format)
-{
-    return worksheet_set_row_opt(self, row_num, height, format, NULL);
-}
-
-/*
- * Merge a range of cells. The first cell should contain the data and the others
- * should be blank. All cells should contain the same format.
- */
-lxw_error
-worksheet_merge_range(lxw_worksheet *self, lxw_row_t first_row,
-                      lxw_col_t first_col, lxw_row_t last_row,
-                      lxw_col_t last_col, const char *string,
-                      lxw_format *format)
-{
-    lxw_merged_range *merged_range;
-    lxw_row_t tmp_row;
-    lxw_col_t tmp_col;
-    lxw_error err;
-
-    /* Excel doesn't allow a single cell to be merged */
-    if (first_row == last_row && first_col == last_col)
-        return LXW_ERROR_PARAMETER_VALIDATION;
-
-    /* Swap last row/col with first row/col as necessary */
-    if (first_row > last_row) {
-        tmp_row = last_row;
-        last_row = first_row;
-        first_row = tmp_row;
-    }
-    if (first_col > last_col) {
-        tmp_col = last_col;
-        last_col = first_col;
-        first_col = tmp_col;
-    }
-
-    /* Check that column number is valid and store the max value */
-    err = _check_dimensions(self, last_row, last_col, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    /* Store the merge range. */
-    merged_range = calloc(1, sizeof(lxw_merged_range));
-    RETURN_ON_MEM_ERROR(merged_range, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    merged_range->first_row = first_row;
-    merged_range->first_col = first_col;
-    merged_range->last_row = last_row;
-    merged_range->last_col = last_col;
-
-    STAILQ_INSERT_TAIL(self->merged_ranges, merged_range, list_pointers);
-    self->merged_range_count++;
-
-    /* Write the first cell */
-    worksheet_write_string(self, first_row, first_col, string, format);
-
-    /* Pad out the rest of the area with formatted blank cells. */
-    for (tmp_row = first_row; tmp_row <= last_row; tmp_row++) {
-        for (tmp_col = first_col; tmp_col <= last_col; tmp_col++) {
-            if (tmp_row == first_row && tmp_col == first_col)
-                continue;
-
-            worksheet_write_blank(self, tmp_row, tmp_col, format);
-        }
-    }
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the autofilter area in the worksheet.
- */
-lxw_error
-worksheet_autofilter(lxw_worksheet *self, lxw_row_t first_row,
-                     lxw_col_t first_col, lxw_row_t last_row,
-                     lxw_col_t last_col)
-{
-    lxw_row_t tmp_row;
-    lxw_col_t tmp_col;
-    lxw_error err;
-
-    /* Excel doesn't allow a single cell to be merged */
-    if (first_row == last_row && first_col == last_col)
-        return LXW_ERROR_PARAMETER_VALIDATION;
-
-    /* Swap last row/col with first row/col as necessary */
-    if (first_row > last_row) {
-        tmp_row = last_row;
-        last_row = first_row;
-        first_row = tmp_row;
-    }
-    if (first_col > last_col) {
-        tmp_col = last_col;
-        last_col = first_col;
-        first_col = tmp_col;
-    }
-
-    /* Check that column number is valid and store the max value */
-    err = _check_dimensions(self, last_row, last_col, LXW_FALSE, LXW_FALSE);
-    if (err)
-        return err;
-
-    self->autofilter.in_use = LXW_TRUE;
-    self->autofilter.first_row = first_row;
-    self->autofilter.first_col = first_col;
-    self->autofilter.last_row = last_row;
-    self->autofilter.last_col = last_col;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set this worksheet as a selected worksheet, i.e. the worksheet has its tab
- * highlighted.
- */
-void
-worksheet_select(lxw_worksheet *self)
-{
-    self->selected = LXW_TRUE;
-
-    /* Selected worksheet can't be hidden. */
-    self->hidden = LXW_FALSE;
-}
-
-/*
- * Set this worksheet as the active worksheet, i.e. the worksheet that is
- * displayed when the workbook is opened. Also set it as selected.
- */
-void
-worksheet_activate(lxw_worksheet *self)
-{
-    self->selected = LXW_TRUE;
-    self->active = LXW_TRUE;
-
-    /* Active worksheet can't be hidden. */
-    self->hidden = LXW_FALSE;
-
-    *self->active_sheet = self->index;
-}
-
-/*
- * Set this worksheet as the first visible sheet. This is necessary
- * when there are a large number of worksheets and the activated
- * worksheet is not visible on the screen.
- */
-void
-worksheet_set_first_sheet(lxw_worksheet *self)
-{
-    /* Active worksheet can't be hidden. */
-    self->hidden = LXW_FALSE;
-
-    *self->first_sheet = self->index;
-}
-
-/*
- * Hide this worksheet.
- */
-void
-worksheet_hide(lxw_worksheet *self)
-{
-    self->hidden = LXW_TRUE;
-
-    /* A hidden worksheet shouldn't be active or selected. */
-    self->selected = LXW_FALSE;
-
-    /* If this is active_sheet or first_sheet reset the workbook value. */
-    if (*self->first_sheet == self->index)
-        *self->first_sheet = 0;
-
-    if (*self->active_sheet == self->index)
-        *self->active_sheet = 0;
-}
-
-/*
- * Set which cell or cells are selected in a worksheet.
- */
-void
-worksheet_set_selection(lxw_worksheet *self,
-                        lxw_row_t first_row, lxw_col_t first_col,
-                        lxw_row_t last_row, lxw_col_t last_col)
-{
-    lxw_selection *selection;
-    lxw_row_t tmp_row;
-    lxw_col_t tmp_col;
-    char active_cell[LXW_MAX_CELL_RANGE_LENGTH];
-    char sqref[LXW_MAX_CELL_RANGE_LENGTH];
-
-    /* Only allow selection to be set once to avoid freeing/re-creating it. */
-    if (!STAILQ_EMPTY(self->selections))
-        return;
-
-    /* Excel doesn't set a selection for cell A1 since it is the default. */
-    if (first_row == 0 && first_col == 0 && last_row == 0 && last_col == 0)
-        return;
-
-    selection = calloc(1, sizeof(lxw_selection));
-    RETURN_VOID_ON_MEM_ERROR(selection);
-
-    /* Set the cell range selection. Do this before swapping max/min to  */
-    /* allow the selection direction to be reversed. */
-    lxw_rowcol_to_cell(active_cell, first_row, first_col);
-
-    /* Swap last row/col for first row/col if necessary. */
-    if (first_row > last_row) {
-        tmp_row = first_row;
-        first_row = last_row;
-        last_row = tmp_row;
-    }
-
-    if (first_col > last_col) {
-        tmp_col = first_col;
-        first_col = last_col;
-        last_col = tmp_col;
-    }
-
-    /* If the first and last cell are the same write a single cell. */
-    if ((first_row == last_row) && (first_col == last_col))
-        lxw_rowcol_to_cell(sqref, first_row, first_col);
-    else
-        lxw_rowcol_to_range(sqref, first_row, first_col, last_row, last_col);
-
-    lxw_strcpy(selection->pane, "");
-    lxw_strcpy(selection->active_cell, active_cell);
-    lxw_strcpy(selection->sqref, sqref);
-
-    STAILQ_INSERT_TAIL(self->selections, selection, list_pointers);
-}
-
-/*
- * Set panes and mark them as frozen. With extra options.
- */
-void
-worksheet_freeze_panes_opt(lxw_worksheet *self,
-                           lxw_row_t first_row, lxw_col_t first_col,
-                           lxw_row_t top_row, lxw_col_t left_col,
-                           uint8_t type)
-{
-    self->panes.first_row = first_row;
-    self->panes.first_col = first_col;
-    self->panes.top_row = top_row;
-    self->panes.left_col = left_col;
-    self->panes.x_split = 0.0;
-    self->panes.y_split = 0.0;
-
-    if (type)
-        self->panes.type = FREEZE_SPLIT_PANES;
-    else
-        self->panes.type = FREEZE_PANES;
-}
-
-/*
- * Set panes and mark them as frozen.
- */
-void
-worksheet_freeze_panes(lxw_worksheet *self,
-                       lxw_row_t first_row, lxw_col_t first_col)
-{
-    worksheet_freeze_panes_opt(self, first_row, first_col,
-                               first_row, first_col, 0);
-}
-
-/*
- * Set panes and mark them as split.With extra options.
- */
-void
-worksheet_split_panes_opt(lxw_worksheet *self,
-                          double y_split, double x_split,
-                          lxw_row_t top_row, lxw_col_t left_col)
-{
-    self->panes.first_row = 0;
-    self->panes.first_col = 0;
-    self->panes.top_row = top_row;
-    self->panes.left_col = left_col;
-    self->panes.x_split = x_split;
-    self->panes.y_split = y_split;
-    self->panes.type = SPLIT_PANES;
-}
-
-/*
- * Set panes and mark them as split.
- */
-void
-worksheet_split_panes(lxw_worksheet *self, double y_split, double x_split)
-{
-    worksheet_split_panes_opt(self, y_split, x_split, 0, 0);
-}
-
-/*
- * Set the page orientation as portrait.
- */
-void
-worksheet_set_portrait(lxw_worksheet *self)
-{
-    self->orientation = LXW_PORTRAIT;
-    self->page_setup_changed = LXW_TRUE;
-}
-
-/*
- * Set the page orientation as landscape.
- */
-void
-worksheet_set_landscape(lxw_worksheet *self)
-{
-    self->orientation = LXW_LANDSCAPE;
-    self->page_setup_changed = LXW_TRUE;
-}
-
-/*
- * Set the page view mode for Mac Excel.
- */
-void
-worksheet_set_page_view(lxw_worksheet *self)
-{
-    self->page_view = LXW_TRUE;
-}
-
-/*
- * Set the paper type. Example. 1 = US Letter, 9 = A4
- */
-void
-worksheet_set_paper(lxw_worksheet *self, uint8_t paper_size)
-{
-    self->paper_size = paper_size;
-    self->page_setup_changed = LXW_TRUE;
-}
-
-/*
- * Set the order in which pages are printed.
- */
-void
-worksheet_print_across(lxw_worksheet *self)
-{
-    self->page_order = LXW_PRINT_ACROSS;
-    self->page_setup_changed = LXW_TRUE;
-}
-
-/*
- * Set all the page margins in inches.
- */
-void
-worksheet_set_margins(lxw_worksheet *self, double left, double right,
-                      double top, double bottom)
-{
-
-    if (left >= 0)
-        self->margin_left = left;
-
-    if (right >= 0)
-        self->margin_right = right;
-
-    if (top >= 0)
-        self->margin_top = top;
-
-    if (bottom >= 0)
-        self->margin_bottom = bottom;
-}
-
-/*
- * Set the page header caption and options.
- */
-lxw_error
-worksheet_set_header_opt(lxw_worksheet *self, const char *string,
-                         lxw_header_footer_options *options)
-{
-    if (options) {
-        if (options->margin >= 0.0)
-            self->margin_header = options->margin;
-    }
-
-    if (!string)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    if (lxw_utf8_strlen(string) >= LXW_HEADER_FOOTER_MAX)
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-
-    lxw_strcpy(self->header, string);
-    self->header_footer_changed = 1;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the page footer caption and options.
- */
-lxw_error
-worksheet_set_footer_opt(lxw_worksheet *self, const char *string,
-                         lxw_header_footer_options *options)
-{
-    if (options) {
-        if (options->margin >= 0.0)
-            self->margin_footer = options->margin;
-    }
-
-    if (!string)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    if (lxw_utf8_strlen(string) >= LXW_HEADER_FOOTER_MAX)
-        return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-
-    lxw_strcpy(self->footer, string);
-    self->header_footer_changed = 1;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the page header caption.
- */
-lxw_error
-worksheet_set_header(lxw_worksheet *self, const char *string)
-{
-    return worksheet_set_header_opt(self, string, NULL);
-}
-
-/*
- * Set the page footer caption.
- */
-lxw_error
-worksheet_set_footer(lxw_worksheet *self, const char *string)
-{
-    return worksheet_set_footer_opt(self, string, NULL);
-}
-
-/*
- * Set the option to show/hide gridlines on the screen and the printed page.
- */
-void
-worksheet_gridlines(lxw_worksheet *self, uint8_t option)
-{
-    if (option == LXW_HIDE_ALL_GRIDLINES) {
-        self->print_gridlines = 0;
-        self->screen_gridlines = 0;
-    }
-
-    if (option & LXW_SHOW_SCREEN_GRIDLINES) {
-        self->screen_gridlines = 1;
-    }
-
-    if (option & LXW_SHOW_PRINT_GRIDLINES) {
-        self->print_gridlines = 1;
-        self->print_options_changed = 1;
-    }
-}
-
-/*
- * Center the page horizontally.
- */
-void
-worksheet_center_horizontally(lxw_worksheet *self)
-{
-    self->print_options_changed = 1;
-    self->hcenter = 1;
-}
-
-/*
- * Center the page horizontally.
- */
-void
-worksheet_center_vertically(lxw_worksheet *self)
-{
-    self->print_options_changed = 1;
-    self->vcenter = 1;
-}
-
-/*
- * Set the option to print the row and column headers on the printed page.
- */
-void
-worksheet_print_row_col_headers(lxw_worksheet *self)
-{
-    self->print_headers = 1;
-    self->print_options_changed = 1;
-}
-
-/*
- * Set the rows to repeat at the top of each printed page.
- */
-lxw_error
-worksheet_repeat_rows(lxw_worksheet *self, lxw_row_t first_row,
-                      lxw_row_t last_row)
-{
-    lxw_row_t tmp_row;
-    lxw_error err;
-
-    if (first_row > last_row) {
-        tmp_row = last_row;
-        last_row = first_row;
-        first_row = tmp_row;
-    }
-
-    err = _check_dimensions(self, last_row, 0, LXW_IGNORE, LXW_IGNORE);
-    if (err)
-        return err;
-
-    self->repeat_rows.in_use = LXW_TRUE;
-    self->repeat_rows.first_row = first_row;
-    self->repeat_rows.last_row = last_row;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the columns to repeat at the left hand side of each printed page.
- */
-lxw_error
-worksheet_repeat_columns(lxw_worksheet *self, lxw_col_t first_col,
-                         lxw_col_t last_col)
-{
-    lxw_col_t tmp_col;
-    lxw_error err;
-
-    if (first_col > last_col) {
-        tmp_col = last_col;
-        last_col = first_col;
-        first_col = tmp_col;
-    }
-
-    err = _check_dimensions(self, last_col, 0, LXW_IGNORE, LXW_IGNORE);
-    if (err)
-        return err;
-
-    self->repeat_cols.in_use = LXW_TRUE;
-    self->repeat_cols.first_col = first_col;
-    self->repeat_cols.last_col = last_col;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the print area in the current worksheet.
- */
-lxw_error
-worksheet_print_area(lxw_worksheet *self, lxw_row_t first_row,
-                     lxw_col_t first_col, lxw_row_t last_row,
-                     lxw_col_t last_col)
-{
-    lxw_row_t tmp_row;
-    lxw_col_t tmp_col;
-    lxw_error err;
-
-    if (first_row > last_row) {
-        tmp_row = last_row;
-        last_row = first_row;
-        first_row = tmp_row;
-    }
-
-    if (first_col > last_col) {
-        tmp_col = last_col;
-        last_col = first_col;
-        first_col = tmp_col;
-    }
-
-    err = _check_dimensions(self, last_row, last_col, LXW_IGNORE, LXW_IGNORE);
-    if (err)
-        return err;
-
-    /* Ignore max area since it is the same as no print area in Excel. */
-    if (first_row == 0 && first_col == 0 && last_row == LXW_ROW_MAX - 1
-        && last_col == LXW_COL_MAX - 1) {
-        return LXW_NO_ERROR;
-    }
-
-    self->print_area.in_use = LXW_TRUE;
-    self->print_area.first_row = first_row;
-    self->print_area.last_row = last_row;
-    self->print_area.first_col = first_col;
-    self->print_area.last_col = last_col;
-
-    return LXW_NO_ERROR;
-}
-
-/* Store the vertical and horizontal number of pages that will define the
- * maximum area printed.
- */
-void
-worksheet_fit_to_pages(lxw_worksheet *self, uint16_t width, uint16_t height)
-{
-    self->fit_page = 1;
-    self->fit_width = width;
-    self->fit_height = height;
-    self->page_setup_changed = 1;
-}
-
-/*
- * Set the start page number.
- */
-void
-worksheet_set_start_page(lxw_worksheet *self, uint16_t start_page)
-{
-    self->page_start = start_page;
-}
-
-/*
- * Set the scale factor for the printed page.
- */
-void
-worksheet_set_print_scale(lxw_worksheet *self, uint16_t scale)
-{
-    /* Confine the scale to Excel"s range */
-    if (scale < 10 || scale > 400)
-        return;
-
-    /* Turn off "fit to page" option. */
-    self->fit_page = LXW_FALSE;
-
-    self->print_scale = scale;
-    self->page_setup_changed = LXW_TRUE;
-}
-
-/*
- * Store the horizontal page breaks on a worksheet.
- */
-lxw_error
-worksheet_set_h_pagebreaks(lxw_worksheet *self, lxw_row_t hbreaks[])
-{
-    uint16_t count = 0;
-
-    if (hbreaks == NULL)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    while (hbreaks[count])
-        count++;
-
-    /* The Excel 2007 specification says that the maximum number of page
-     * breaks is 1026. However, in practice it is actually 1023. */
-    if (count > LXW_BREAKS_MAX)
-        count = LXW_BREAKS_MAX;
-
-    self->hbreaks = calloc(count, sizeof(lxw_row_t));
-    RETURN_ON_MEM_ERROR(self->hbreaks, LXW_ERROR_MEMORY_MALLOC_FAILED);
-    memcpy(self->hbreaks, hbreaks, count * sizeof(lxw_row_t));
-    self->hbreaks_count = count;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Store the vertical page breaks on a worksheet.
- */
-lxw_error
-worksheet_set_v_pagebreaks(lxw_worksheet *self, lxw_col_t vbreaks[])
-{
-    uint16_t count = 0;
-
-    if (vbreaks == NULL)
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-
-    while (vbreaks[count])
-        count++;
-
-    /* The Excel 2007 specification says that the maximum number of page
-     * breaks is 1026. However, in practice it is actually 1023. */
-    if (count > LXW_BREAKS_MAX)
-        count = LXW_BREAKS_MAX;
-
-    self->vbreaks = calloc(count, sizeof(lxw_col_t));
-    RETURN_ON_MEM_ERROR(self->vbreaks, LXW_ERROR_MEMORY_MALLOC_FAILED);
-    memcpy(self->vbreaks, vbreaks, count * sizeof(lxw_col_t));
-    self->vbreaks_count = count;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Set the worksheet zoom factor.
- */
-void
-worksheet_set_zoom(lxw_worksheet *self, uint16_t scale)
-{
-    /* Confine the scale to Excel"s range */
-    if (scale < 10 || scale > 400) {
-        LXW_WARN("worksheet_set_zoom(): "
-                 "Zoom factor scale outside range: 10 <= zoom <= 400.");
-        return;
-    }
-
-    self->zoom = scale;
-}
-
-/*
- * Hide cell zero values.
- */
-void
-worksheet_hide_zero(lxw_worksheet *self)
-{
-    self->show_zeros = LXW_FALSE;
-}
-
-/*
- * Display the worksheet right to left for some eastern versions of Excel.
- */
-void
-worksheet_right_to_left(lxw_worksheet *self)
-{
-    self->right_to_left = LXW_TRUE;
-}
-
-/*
- * Set the color of the worksheet tab.
- */
-void
-worksheet_set_tab_color(lxw_worksheet *self, lxw_color_t color)
-{
-    self->tab_color = color;
-}
-
-/*
- * Set the worksheet protection flags to prevent modification of worksheet
- * objects.
- */
-void
-worksheet_protect(lxw_worksheet *self, const char *password,
-                  lxw_protection *options)
-{
-    struct lxw_protection *protect = &self->protection;
-
-    /* Copy any user parameters to the internal structure. */
-    if (options) {
-        protect->no_select_locked_cells = options->no_select_locked_cells;
-        protect->no_select_unlocked_cells = options->no_select_unlocked_cells;
-        protect->format_cells = options->format_cells;
-        protect->format_columns = options->format_columns;
-        protect->format_rows = options->format_rows;
-        protect->insert_columns = options->insert_columns;
-        protect->insert_rows = options->insert_rows;
-        protect->insert_hyperlinks = options->insert_hyperlinks;
-        protect->delete_columns = options->delete_columns;
-        protect->delete_rows = options->delete_rows;
-        protect->sort = options->sort;
-        protect->autofilter = options->autofilter;
-        protect->pivot_tables = options->pivot_tables;
-        protect->scenarios = options->scenarios;
-        protect->objects = options->objects;
-    }
-
-    if (password) {
-        uint16_t hash = _hash_password(password);
-        lxw_snprintf(protect->hash, 5, "%X", hash);
-    }
-
-    protect->is_configured = LXW_TRUE;
-}
-
-/*
- * Set the worksheet properties for outlines and grouping.
- */
-void
-worksheet_outline_settings(lxw_worksheet *self,
-                           uint8_t visible,
-                           uint8_t symbols_below,
-                           uint8_t symbols_right, uint8_t auto_style)
-{
-    self->outline_on = visible;
-    self->outline_below = symbols_below;
-    self->outline_right = symbols_right;
-    self->outline_style = auto_style;
-
-    self->outline_changed = LXW_TRUE;
-}
-
-/*
- * Set the default row properties
- */
-void
-worksheet_set_default_row(lxw_worksheet *self, double height,
-                          uint8_t hide_unused_rows)
-{
-    if (height < 0)
-        height = self->default_row_height;
-
-    if (height != self->default_row_height) {
-        self->default_row_height = height;
-        self->row_size_changed = LXW_TRUE;
-    }
-
-    if (hide_unused_rows)
-        self->default_row_zeroed = LXW_TRUE;
-
-    self->default_row_set = LXW_TRUE;
-}
-
-/*
- * Insert an image into the worksheet.
- */
-lxw_error
-worksheet_insert_image_opt(lxw_worksheet *self,
-                           lxw_row_t row_num, lxw_col_t col_num,
-                           const char *filename,
-                           lxw_image_options *user_options)
-{
-    FILE *image_stream;
-    char *short_name;
-    lxw_image_options *options;
-
-    if (!filename) {
-        LXW_WARN("worksheet_insert_image()/_opt(): "
-                 "filename must be specified.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    /* Check that the image file exists and can be opened. */
-    image_stream = fopen(filename, "rb");
-    if (!image_stream) {
-        LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                         "file doesn't exist or can't be opened: %s.",
-                         filename);
-        return LXW_ERROR_PARAMETER_VALIDATION;
-    }
-
-    /* Get the filename from the full path to add to the Drawing object. */
-    short_name = lxw_basename(filename);
-    if (!short_name) {
-        LXW_WARN_FORMAT1("worksheet_insert_image()/_opt(): "
-                         "couldn't get basename for file: %s.", filename);
-        fclose(image_stream);
-        return LXW_ERROR_PARAMETER_VALIDATION;
-    }
-
-    /* Create a new object to hold the image options. */
-    options = calloc(1, sizeof(lxw_image_options));
-    if (!options) {
-        fclose(image_stream);
-        return LXW_ERROR_MEMORY_MALLOC_FAILED;
-    }
-
-    if (user_options) {
-        options->x_offset = user_options->x_offset;
-        options->y_offset = user_options->y_offset;
-        options->x_scale = user_options->x_scale;
-        options->y_scale = user_options->y_scale;
-    }
-
-    /* Copy other options or set defaults. */
-    options->filename = lxw_strdup(filename);
-    options->short_name = lxw_strdup(short_name);
-    options->stream = image_stream;
-    options->row = row_num;
-    options->col = col_num;
-
-    if (!options->x_scale)
-        options->x_scale = 1;
-
-    if (!options->y_scale)
-        options->y_scale = 1;
-
-    if (_get_image_properties(options) == LXW_NO_ERROR) {
-        STAILQ_INSERT_TAIL(self->image_data, options, list_pointers);
-        fclose(image_stream);
-        return LXW_NO_ERROR;
-    }
-    else {
-        free(options);
-        fclose(image_stream);
-        return LXW_ERROR_IMAGE_DIMENSIONS;
-    }
-}
-
-/*
- * Insert an image into the worksheet.
- */
-lxw_error
-worksheet_insert_image(lxw_worksheet *self,
-                       lxw_row_t row_num, lxw_col_t col_num,
-                       const char *filename)
-{
-    return worksheet_insert_image_opt(self, row_num, col_num, filename, NULL);
-}
-
-/*
- * Insert an chart into the worksheet.
- */
-lxw_error
-worksheet_insert_chart_opt(lxw_worksheet *self,
-                           lxw_row_t row_num, lxw_col_t col_num,
-                           lxw_chart *chart, lxw_image_options *user_options)
-{
-    lxw_image_options *options;
-    lxw_chart_series *series;
-
-    if (!chart) {
-        LXW_WARN("worksheet_insert_chart()/_opt(): chart must be non-NULL.");
-        return LXW_ERROR_NULL_PARAMETER_IGNORED;
-    }
-
-    /* Check that the chart isn't being used more than once. */
-    if (chart->in_use) {
-        LXW_WARN("worksheet_insert_chart()/_opt(): the same chart object "
-                 "cannot be inserted in a worksheet more than once.");
-
-        return LXW_ERROR_PARAMETER_VALIDATION;
-    }
-
-    /* Check that the chart has a data series. */
-    if (STAILQ_EMPTY(chart->series_list)) {
-        LXW_WARN
-            ("worksheet_insert_chart()/_opt(): chart must have a series.");
-
-        return LXW_ERROR_PARAMETER_VALIDATION;
-    }
-
-    /* Check that the chart has a 'values' series. */
-    STAILQ_FOREACH(series, chart->series_list, list_pointers) {
-        if (!series->values->formula && !series->values->sheetname) {
-            LXW_WARN("worksheet_insert_chart()/_opt(): chart must have a "
-                     "'values' series.");
-
-            return LXW_ERROR_PARAMETER_VALIDATION;
-        }
-    }
-
-    /* Create a new object to hold the chart image options. */
-    options = calloc(1, sizeof(lxw_image_options));
-    RETURN_ON_MEM_ERROR(options, LXW_ERROR_MEMORY_MALLOC_FAILED);
-
-    if (user_options) {
-        options->x_offset = user_options->x_offset;
-        options->y_offset = user_options->y_offset;
-        options->x_scale = user_options->x_scale;
-        options->y_scale = user_options->y_scale;
-    }
-
-    /* Copy other options or set defaults. */
-    options->row = row_num;
-    options->col = col_num;
-
-    /* TODO. Read defaults from chart. */
-    options->width = 480;
-    options->height = 288;
-
-    if (!options->x_scale)
-        options->x_scale = 1;
-
-    if (!options->y_scale)
-        options->y_scale = 1;
-
-    /* Store chart references so they can be ordered in the workbook. */
-    options->chart = chart;
-
-    STAILQ_INSERT_TAIL(self->chart_data, options, list_pointers);
-
-    chart->in_use = LXW_TRUE;
-
-    return LXW_NO_ERROR;
-}
-
-/*
- * Insert an image into the worksheet.
- */
-lxw_error
-worksheet_insert_chart(lxw_worksheet *self,
-                       lxw_row_t row_num, lxw_col_t col_num, lxw_chart *chart)
-{
-    return worksheet_insert_chart_opt(self, row_num, col_num, chart, NULL);
-}
-
-/*
- * Add a data validation to a worksheet, for a range. Ironically this requires
- * a lot of validation of the user input.
- */
-lxw_error
-worksheet_data_validation_range(lxw_worksheet *self, lxw_row_t first_row,
-                                lxw_col_t first_col,
-                                lxw_row_t last_row,
-                                lxw_col_t last_col,
-                                lxw_data_validation *validation)
-{
-    lxw_data_validation *copy;
-    uint8_t is_between = LXW_FALSE;
-    uint8_t is_formula = LXW_FALSE;
-    uint8_t has_criteria = LXW_TRUE;
-    lxw_error err;
-    lxw_row_t tmp_row;
-    lxw_col_t tmp_col;
-    size_t length;
-
-    /* No action is required for validation type 'any' unless there are
-     * input messages to display.*/
-    if (validation->validate == LXW_VALIDATION_TYPE_ANY
-        && !(validation->input_title || validation->input_message)) {
-
-        return LXW_NO_ERROR;
-    }
-
-    /* Check for formula types. */
-    switch (validation->validate) {
-        case LXW_VALIDATION_TYPE_INTEGER_FORMULA:
-        case LXW_VALIDATION_TYPE_DECIMAL_FORMULA:
-        case LXW_VALIDATION_TYPE_LIST_FORMULA:
-        case LXW_VALIDATION_TYPE_LENGTH_FORMULA:
-        case LXW_VALIDATION_TYPE_DATE_FORMULA:
-        case LXW_VALIDATION_TYPE_TIME_FORMULA:
-        case LXW_VALIDATION_TYPE_CUSTOM_FORMULA:
-            is_formula = LXW_TRUE;
-            break;
-    }
-
-    /* Check for types without a criteria. */
-    switch (validation->validate) {
-        case LXW_VALIDATION_TYPE_LIST:
-        case LXW_VALIDATION_TYPE_LIST_FORMULA:
-        case LXW_VALIDATION_TYPE_ANY:
-        case LXW_VALIDATION_TYPE_CUSTOM_FORMULA:
-            has_criteria = LXW_FALSE;
-            break;
-    }
-
-    /* Check that a validation parameter has been specified
-     * except for 'list', 'any' and 'custom'. */
-    if (has_criteria && validation->criteria == LXW_VALIDATION_CRITERIA_NONE) {
-
-        LXW_WARN_FORMAT("worksheet_data_validation_cell()/_range(): "
-                        "criteria parameter must be specified.");
-        return LXW_ERROR_PARAMETER_VALIDATION;
-    }
-
-    /* Check for "between" criteria so we can do additional checks. */
-    if (has_criteria
-        && (validation->criteria == LXW_VALIDATION_CRITERIA_BETWEEN
-            || validation->criteria == LXW_VALIDATION_CRITERIA_NOT_BETWEEN)) {
-
-        is_between = LXW_TRUE;
-    }
-
-    /* Check that formula values are non NULL. */
-    if (is_formula) {
-        if (is_between) {
-            if (!validation->minimum_formula) {
-                LXW_WARN_FORMAT("worksheet_data_validation_cell()/_range(): "
-                                "minimum_formula parameter cannot be NULL.");
-                return LXW_ERROR_PARAMETER_VALIDATION;
-            }
-            if (!validation->maximum_formula) {
-                LXW_WARN_FORMAT("worksheet_data_validation_cell()/_range(): "
-                                "maximum_formula parameter cannot be NULL.");
-                return LXW_ERROR_PARAMETER_VALIDATION;
-            }
-        }
-        else {
-            if (!validation->value_formula) {
-                LXW_WARN_FORMAT("worksheet_data_validation_cell()/_range(): "
-                                "formula parameter cannot be NULL.");
-                return LXW_ERROR_PARAMETER_VALIDATION;
-            }
-        }
-    }
-
-    /* Check Excel limitations on input strings. */
-    if (validation->input_title) {
-        length = lxw_utf8_strlen(validation->input_title);
-        if (length > LXW_VALIDATION_MAX_TITLE_LENGTH) {
-            LXW_WARN_FORMAT1("worksheet_data_validation_cell()/_range(): "
-                             "input_title length > Excel limit of %d.",
-                             LXW_VALIDATION_MAX_TITLE_LENGTH);
-            return LXW_ERROR_32_STRING_LENGTH_EXCEEDED;
-        }
-    }
-
-    if (validation->error_title) {
-        length = lxw_utf8_strlen(validation->error_title);
-        if (length > LXW_VALIDATION_MAX_TITLE_LENGTH) {
-            LXW_WARN_FORMAT1("worksheet_data_validation_cell()/_range(): "
-                             "error_title length > Excel limit of %d.",
-                             LXW_VALIDATION_MAX_TITLE_LENGTH);
-            return LXW_ERROR_32_STRING_LENGTH_EXCEEDED;
-        }
-    }
-
-    if (validation->input_message) {
-        length = lxw_utf8_strlen(validation->input_message);
-        if (length > LXW_VALIDATION_MAX_STRING_LENGTH) {
-            LXW_WARN_FORMAT1("worksheet_data_validation_cell()/_range(): "
-                             "input_message length > Excel limit of %d.",
-                             LXW_VALIDATION_MAX_STRING_LENGTH);
-            return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-        }
-    }
-
-    if (validation->error_message) {
-        length = lxw_utf8_strlen(validation->error_message);
-        if (length > LXW_VALIDATION_MAX_STRING_LENGTH) {
-            LXW_WARN_FORMAT1("worksheet_data_validation_cell()/_range(): "
-                             "error_message length > Excel limit of %d.",
-                             LXW_VALIDATION_MAX_STRING_LENGTH);
-            return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-        }
-    }
-
-    if (validation->validate == LXW_VALIDATION_TYPE_LIST) {
-        length = _validation_list_length(validation->value_list);
-
-        if (length == 0) {
-            LXW_WARN_FORMAT("worksheet_data_validation_cell()/_range(): "
-                            "list parameters cannot be zero.");
-            return LXW_ERROR_PARAMETER_VALIDATION;
-        }
-
-        if (length > LXW_VALIDATION_MAX_STRING_LENGTH) {
-            LXW_WARN_FORMAT1("worksheet_data_validation_cell()/_range(): "
-                             "list length with commas > Excel limit of %d.",
-                             LXW_VALIDATION_MAX_STRING_LENGTH);
-            return LXW_ERROR_255_STRING_LENGTH_EXCEEDED;
-        }
-    }
-
-    /* Swap last row/col with first row/col as necessary */
-    if (first_row > last_row) {
-        tmp_row = last_row;
-        last_row = first_row;
-        first_row = tmp_row;
-    }
-    if (first_col > last_col) {
-        tmp_col = last_col;
-        last_col = first_col;
-        first_col = tmp_col;
-    }
-
-    /* Check that dimensions are valid but don't store them. */
-    err = _check_dimensions(self, last_row, last_col, LXW_TRUE, LXW_TRUE);
-    if (err)
-        return err;
-
-    /* Create a copy of the parameters from the user data validation. */
-    copy = calloc(1, sizeof(lxw_data_validation));
-    GOTO_LABEL_ON_MEM_ERROR(copy, mem_error);
-
-    /* Create the data validation range. */
-    if (first_row == last_row && first_col == last_col)
-        lxw_rowcol_to_cell(copy->sqref, first_row, last_col);
-    else
-        lxw_rowcol_to_range(copy->sqref, first_row, first_col, last_row,
-                            last_col);
-
-    /* Copy the parameters from the user data validation. */
-    copy->validate = validation->validate;
-    copy->value_number = validation->value_number;
-    copy->error_type = validation->error_type;
-    copy->dropdown = validation->dropdown;
-    copy->is_between = is_between;
-
-    if (has_criteria)
-        copy->criteria = validation->criteria;
-
-    if (is_between) {
-        copy->value_number = validation->minimum_number;
-        copy->maximum_number = validation->maximum_number;
-    }
-
-    /* Copy the input/error titles and messages. */
-    if (validation->input_title) {
-        copy->input_title = lxw_strdup_formula(validation->input_title);
-        GOTO_LABEL_ON_MEM_ERROR(copy->input_title, mem_error);
-    }
-
-    if (validation->input_message) {
-        copy->input_message = lxw_strdup_formula(validation->input_message);
-        GOTO_LABEL_ON_MEM_ERROR(copy->input_message, mem_error);
-    }
-
-    if (validation->error_title) {
-        copy->error_title = lxw_strdup_formula(validation->error_title);
-        GOTO_LABEL_ON_MEM_ERROR(copy->error_title, mem_error);
-    }
-
-    if (validation->error_message) {
-        copy->error_message = lxw_strdup_formula(validation->error_message);
-        GOTO_LABEL_ON_MEM_ERROR(copy->error_message, mem_error);
-    }
-
-    /* Copy the formula strings. */
-    if (is_formula) {
-        if (is_between) {
-            copy->value_formula =
-                lxw_strdup_formula(validation->minimum_formula);
-            GOTO_LABEL_ON_MEM_ERROR(copy->value_formula, mem_error);
-            copy->maximum_formula =
-                lxw_strdup_formula(validation->maximum_formula);
-            GOTO_LABEL_ON_MEM_ERROR(copy->maximum_formula, mem_error);
-        }
-        else {
-            copy->value_formula =
-                lxw_strdup_formula(validation->value_formula);
-            GOTO_LABEL_ON_MEM_ERROR(copy->value_formula, mem_error);
-        }
-    }
-
-    /* Copy the validation list as a csv string. */
-    if (validation->validate == LXW_VALIDATION_TYPE_LIST) {
-        copy->value_formula = _validation_list_to_csv(validation->value_list);
-        GOTO_LABEL_ON_MEM_ERROR(copy->value_formula, mem_error);
-    }
-
-    if (validation->validate == LXW_VALIDATION_TYPE_LIST_FORMULA) {
-        copy->value_formula = lxw_strdup_formula(validation->value_formula);
-        GOTO_LABEL_ON_MEM_ERROR(copy->value_formula, mem_error);
-    }
-
-    if (validation->validate == LXW_VALIDATION_TYPE_DATE
-        || validation->validate == LXW_VALIDATION_TYPE_TIME) {
-        if (is_between) {
-            copy->value_number =
-                lxw_datetime_to_excel_date(&validation->minimum_datetime,
-                                           LXW_EPOCH_1900);
-            copy->maximum_number =
-                lxw_datetime_to_excel_date(&validation->maximum_datetime,
-                                           LXW_EPOCH_1900);
-        }
-        else {
-            copy->value_number =
-                lxw_datetime_to_excel_date(&validation->value_datetime,
-                                           LXW_EPOCH_1900);
-        }
-    }
-
-    /* These options are on by default so we can't take plain booleans. */
-    copy->ignore_blank = validation->ignore_blank ^ 1;
-    copy->show_input = validation->show_input ^ 1;
-    copy->show_error = validation->show_error ^ 1;
-
-    STAILQ_INSERT_TAIL(self->data_validations, copy, list_pointers);
-
-    self->num_validations++;
-
-    return LXW_NO_ERROR;
-
-mem_error:
-    _free_data_validation(copy);
-    return LXW_ERROR_MEMORY_MALLOC_FAILED;
-}
-
-/*
- * Add a data validation to a worksheet, for a cell.
- */
-lxw_error
-worksheet_data_validation_cell(lxw_worksheet *self, lxw_row_t row,
-                               lxw_col_t col, lxw_data_validation *validation)
-{
-    return worksheet_data_validation_range(self, row, col,
-                                           row, col, validation);
-}

+ 0 - 728
library/src/xlsx_format.c

@@ -1,728 +0,0 @@
-/*****************************************************************************
- * format - A library for creating Excel XLSX format files.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include "xlsxwriter/xmlwriter.h"
-#include "xlsxwriter/format.h"
-#include "xlsxwriter/utility.h"
-
-/*****************************************************************************
- *
- * Private functions.
- *
- ****************************************************************************/
-
-/*
- * Create a new format object.
- */
-lxw_format *
-lxw_format_new()
-{
-    lxw_format *format = calloc(1, sizeof(lxw_format));
-    GOTO_LABEL_ON_MEM_ERROR(format, mem_error);
-
-    format->xf_format_indices = NULL;
-
-    format->xf_index = LXW_PROPERTY_UNSET;
-    format->dxf_index = LXW_PROPERTY_UNSET;
-
-    format->font_name[0] = '\0';
-    format->font_scheme[0] = '\0';
-    format->num_format[0] = '\0';
-    format->num_format_index = 0;
-    format->font_index = 0;
-    format->has_font = LXW_FALSE;
-    format->has_dxf_font = LXW_FALSE;
-    format->font_size = 11.0;
-    format->bold = LXW_FALSE;
-    format->italic = LXW_FALSE;
-    format->font_color = LXW_COLOR_UNSET;
-    format->underline = LXW_FALSE;
-    format->font_strikeout = LXW_FALSE;
-    format->font_outline = LXW_FALSE;
-    format->font_shadow = LXW_FALSE;
-    format->font_script = LXW_FALSE;
-    format->font_family = LXW_DEFAULT_FONT_FAMILY;
-    format->font_charset = LXW_FALSE;
-    format->font_condense = LXW_FALSE;
-    format->font_extend = LXW_FALSE;
-    format->theme = LXW_FALSE;
-    format->hyperlink = LXW_FALSE;
-
-    format->hidden = LXW_FALSE;
-    format->locked = LXW_TRUE;
-
-    format->text_h_align = LXW_ALIGN_NONE;
-    format->text_wrap = LXW_FALSE;
-    format->text_v_align = LXW_ALIGN_NONE;
-    format->text_justlast = LXW_FALSE;
-    format->rotation = 0;
-
-    format->fg_color = LXW_COLOR_UNSET;
-    format->bg_color = LXW_COLOR_UNSET;
-    format->pattern = LXW_PATTERN_NONE;
-    format->has_fill = LXW_FALSE;
-    format->has_dxf_fill = LXW_FALSE;
-    format->fill_index = 0;
-    format->fill_count = 0;
-
-    format->border_index = 0;
-    format->has_border = LXW_FALSE;
-    format->has_dxf_border = LXW_FALSE;
-    format->border_count = 0;
-
-    format->bottom = LXW_BORDER_NONE;
-    format->left = LXW_BORDER_NONE;
-    format->right = LXW_BORDER_NONE;
-    format->top = LXW_BORDER_NONE;
-    format->diag_border = LXW_BORDER_NONE;
-    format->diag_type = LXW_BORDER_NONE;
-    format->bottom_color = LXW_COLOR_UNSET;
-    format->left_color = LXW_COLOR_UNSET;
-    format->right_color = LXW_COLOR_UNSET;
-    format->top_color = LXW_COLOR_UNSET;
-    format->diag_color = LXW_COLOR_UNSET;
-
-    format->indent = 0;
-    format->shrink = LXW_FALSE;
-    format->merge_range = LXW_FALSE;
-    format->reading_order = 0;
-    format->just_distrib = LXW_FALSE;
-    format->color_indexed = LXW_FALSE;
-    format->font_only = LXW_FALSE;
-
-    return format;
-
-mem_error:
-    lxw_format_free(format);
-    return NULL;
-}
-
-/*
- * Free a format object.
- */
-void
-lxw_format_free(lxw_format *format)
-{
-    if (!format)
-        return;
-
-    free(format);
-    format = NULL;
-}
-
-/*
- * Check a user input color.
- */
-lxw_color_t
-lxw_format_check_color(lxw_color_t color)
-{
-    if (color == LXW_COLOR_UNSET)
-        return color;
-    else
-        return color & LXW_COLOR_MASK;
-}
-
-/*
- * Check a user input border.
- */
-STATIC uint8_t
-_check_border(uint8_t border)
-{
-    if (border >= LXW_BORDER_THIN && border <= LXW_BORDER_SLANT_DASH_DOT)
-        return border;
-    else
-        return LXW_BORDER_NONE;
-}
-
-/*****************************************************************************
- *
- * Public functions.
- *
- ****************************************************************************/
-
-/*
- * Returns a format struct suitable for hashing as a lookup key. This is
- * mainly a memcpy with any pointer members set to NULL.
- */
-STATIC lxw_format *
-_get_format_key(lxw_format *self)
-{
-    lxw_format *key = calloc(1, sizeof(lxw_format));
-    GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
-
-    memcpy(key, self, sizeof(lxw_format));
-
-    /* Set pointer members to NULL since they aren't part of the comparison. */
-    key->xf_format_indices = NULL;
-    key->num_xf_formats = NULL;
-    key->list_pointers.stqe_next = NULL;
-
-    return key;
-
-mem_error:
-    return NULL;
-}
-
-/*
- * Returns a font struct suitable for hashing as a lookup key.
- */
-lxw_font *
-lxw_format_get_font_key(lxw_format *self)
-{
-    lxw_font *key = calloc(1, sizeof(lxw_font));
-    GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
-
-    LXW_FORMAT_FIELD_COPY(key->font_name, self->font_name);
-    key->font_size = self->font_size;
-    key->bold = self->bold;
-    key->italic = self->italic;
-    key->font_color = self->font_color;
-    key->underline = self->underline;
-    key->font_strikeout = self->font_strikeout;
-    key->font_outline = self->font_outline;
-    key->font_shadow = self->font_shadow;
-    key->font_script = self->font_script;
-    key->font_family = self->font_family;
-    key->font_charset = self->font_charset;
-    key->font_condense = self->font_condense;
-    key->font_extend = self->font_extend;
-
-    return key;
-
-mem_error:
-    return NULL;
-}
-
-/*
- * Returns a border struct suitable for hashing as a lookup key.
- */
-lxw_border *
-lxw_format_get_border_key(lxw_format *self)
-{
-    lxw_border *key = calloc(1, sizeof(lxw_border));
-    GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
-
-    key->bottom = self->bottom;
-    key->left = self->left;
-    key->right = self->right;
-    key->top = self->top;
-    key->diag_border = self->diag_border;
-    key->diag_type = self->diag_type;
-    key->bottom_color = self->bottom_color;
-    key->left_color = self->left_color;
-    key->right_color = self->right_color;
-    key->top_color = self->top_color;
-    key->diag_color = self->diag_color;
-
-    return key;
-
-mem_error:
-    return NULL;
-}
-
-/*
- * Returns a pattern fill struct suitable for hashing as a lookup key.
- */
-lxw_fill *
-lxw_format_get_fill_key(lxw_format *self)
-{
-    lxw_fill *key = calloc(1, sizeof(lxw_fill));
-    GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
-
-    key->fg_color = self->fg_color;
-    key->bg_color = self->bg_color;
-    key->pattern = self->pattern;
-
-    return key;
-
-mem_error:
-    return NULL;
-}
-
-/*
- * Returns the XF index number used by Excel to identify a format.
- */
-int32_t
-lxw_format_get_xf_index(lxw_format *self)
-{
-    lxw_format *format_key;
-    lxw_format *existing_format;
-    lxw_hash_element *hash_element;
-    lxw_hash_table *formats_hash_table = self->xf_format_indices;
-    int32_t index;
-
-    /* Note: The formats_hash_table/xf_format_indices contains the unique and
-     * more importantly the *used* formats in the workbook.
-     */
-
-    /* Format already has an index number so return it. */
-    if (self->xf_index != LXW_PROPERTY_UNSET) {
-        return self->xf_index;
-    }
-
-    /* Otherwise, the format doesn't have an index number so we assign one.
-     * First generate a unique key to identify the format in the hash table.
-     */
-    format_key = _get_format_key(self);
-
-    /* Return the default format index if the key generation failed. */
-    if (!format_key)
-        return 0;
-
-    /* Look up the format in the hash table. */
-    hash_element =
-        lxw_hash_key_exists(formats_hash_table, format_key,
-                            sizeof(lxw_format));
-
-    if (hash_element) {
-        /* Format matches existing format with an index. */
-        free(format_key);
-        existing_format = hash_element->value;
-        return existing_format->xf_index;
-    }
-    else {
-        /* New format requiring an index. */
-        index = formats_hash_table->unique_count;
-        self->xf_index = index;
-        lxw_insert_hash_element(formats_hash_table, format_key, self,
-                                sizeof(lxw_format));
-        return index;
-    }
-}
-
-/*
- * Set the font_name property.
- */
-void
-format_set_font_name(lxw_format *self, const char *font_name)
-{
-    LXW_FORMAT_FIELD_COPY(self->font_name, font_name);
-}
-
-/*
- * Set the font_size property.
- */
-void
-format_set_font_size(lxw_format *self, double size)
-{
-
-    if (size >= LXW_MIN_FONT_SIZE && size <= LXW_MAX_FONT_SIZE)
-        self->font_size = size;
-}
-
-/*
- * Set the font_color property.
- */
-void
-format_set_font_color(lxw_format *self, lxw_color_t color)
-{
-    self->font_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the bold property.
- */
-void
-format_set_bold(lxw_format *self)
-{
-    self->bold = LXW_TRUE;
-}
-
-/*
- * Set the italic property.
- */
-
-void
-format_set_italic(lxw_format *self)
-{
-    self->italic = LXW_TRUE;
-}
-
-/*
- * Set the underline property.
- */
-void
-format_set_underline(lxw_format *self, uint8_t style)
-{
-    if (style >= LXW_UNDERLINE_SINGLE
-        && style <= LXW_UNDERLINE_DOUBLE_ACCOUNTING)
-        self->underline = style;
-}
-
-/*
- * Set the font_strikeout property.
- */
-void
-format_set_font_strikeout(lxw_format *self)
-{
-    self->font_strikeout = LXW_TRUE;
-}
-
-/*
- * Set the font_script property.
- */
-void
-format_set_font_script(lxw_format *self, uint8_t style)
-{
-    if (style >= LXW_FONT_SUPERSCRIPT && style <= LXW_FONT_SUBSCRIPT)
-        self->font_script = style;
-}
-
-/*
- * Set the font_outline property.
- */
-void
-format_set_font_outline(lxw_format *self)
-{
-    self->font_outline = LXW_TRUE;
-}
-
-/*
- * Set the font_shadow property.
- */
-void
-format_set_font_shadow(lxw_format *self)
-{
-    self->font_shadow = LXW_TRUE;
-}
-
-/*
- * Set the num_format property.
- */
-void
-format_set_num_format(lxw_format *self, const char *num_format)
-{
-    LXW_FORMAT_FIELD_COPY(self->num_format, num_format);
-}
-
-/*
- * Set the unlocked property.
- */
-void
-format_set_unlocked(lxw_format *self)
-{
-    self->locked = LXW_FALSE;
-}
-
-/*
- * Set the hidden property.
- */
-void
-format_set_hidden(lxw_format *self)
-{
-    self->hidden = LXW_TRUE;
-}
-
-/*
- * Set the align property.
- */
-void
-format_set_align(lxw_format *self, uint8_t value)
-{
-    if (value >= LXW_ALIGN_LEFT && value <= LXW_ALIGN_DISTRIBUTED) {
-        self->text_h_align = value;
-    }
-
-    if (value >= LXW_ALIGN_VERTICAL_TOP
-        && value <= LXW_ALIGN_VERTICAL_DISTRIBUTED) {
-        self->text_v_align = value;
-    }
-}
-
-/*
- * Set the text_wrap property.
- */
-void
-format_set_text_wrap(lxw_format *self)
-{
-    self->text_wrap = LXW_TRUE;
-}
-
-/*
- * Set the rotation property.
- */
-void
-format_set_rotation(lxw_format *self, int16_t angle)
-{
-    /* Convert user angle to Excel angle. */
-    if (angle == 270) {
-        self->rotation = 255;
-    }
-    else if (angle >= -90 || angle <= 90) {
-        if (angle < 0)
-            angle = -angle + 90;
-
-        self->rotation = angle;
-    }
-    else {
-        LXW_WARN("Rotation rotation outside range: -90 <= angle <= 90.");
-        self->rotation = 0;
-    }
-}
-
-/*
- * Set the indent property.
- */
-void
-format_set_indent(lxw_format *self, uint8_t value)
-{
-    self->indent = value;
-}
-
-/*
- * Set the shrink property.
- */
-void
-format_set_shrink(lxw_format *self)
-{
-    self->shrink = LXW_TRUE;
-}
-
-/*
- * Set the text_justlast property.
- */
-void
-format_set_text_justlast(lxw_format *self)
-{
-    self->text_justlast = LXW_TRUE;
-}
-
-/*
- * Set the pattern property.
- */
-void
-format_set_pattern(lxw_format *self, uint8_t value)
-{
-    self->pattern = value;
-}
-
-/*
- * Set the bg_color property.
- */
-void
-format_set_bg_color(lxw_format *self, lxw_color_t color)
-{
-    self->bg_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the fg_color property.
- */
-void
-format_set_fg_color(lxw_format *self, lxw_color_t color)
-{
-    self->fg_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the border property.
- */
-void
-format_set_border(lxw_format *self, uint8_t style)
-{
-    style = _check_border(style);
-    self->bottom = style;
-    self->top = style;
-    self->left = style;
-    self->right = style;
-}
-
-/*
- * Set the border_color property.
- */
-void
-format_set_border_color(lxw_format *self, lxw_color_t color)
-{
-    color = lxw_format_check_color(color);
-    self->bottom_color = color;
-    self->top_color = color;
-    self->left_color = color;
-    self->right_color = color;
-}
-
-/*
- * Set the bottom property.
- */
-void
-format_set_bottom(lxw_format *self, uint8_t style)
-{
-    self->bottom = _check_border(style);
-}
-
-/*
- * Set the bottom_color property.
- */
-void
-format_set_bottom_color(lxw_format *self, lxw_color_t color)
-{
-    self->bottom_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the left property.
- */
-void
-format_set_left(lxw_format *self, uint8_t style)
-{
-    self->left = _check_border(style);
-}
-
-/*
- * Set the left_color property.
- */
-void
-format_set_left_color(lxw_format *self, lxw_color_t color)
-{
-    self->left_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the right property.
- */
-void
-format_set_right(lxw_format *self, uint8_t style)
-{
-    self->right = _check_border(style);
-}
-
-/*
- * Set the right_color property.
- */
-void
-format_set_right_color(lxw_format *self, lxw_color_t color)
-{
-    self->right_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the top property.
- */
-void
-format_set_top(lxw_format *self, uint8_t style)
-{
-    self->top = _check_border(style);
-}
-
-/*
- * Set the top_color property.
- */
-void
-format_set_top_color(lxw_format *self, lxw_color_t color)
-{
-    self->top_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the diag_type property.
- */
-void
-format_set_diag_type(lxw_format *self, uint8_t type)
-{
-    if (type >= LXW_DIAGONAL_BORDER_UP && type <= LXW_DIAGONAL_BORDER_UP_DOWN)
-        self->diag_type = type;
-}
-
-/*
- * Set the diag_color property.
- */
-void
-format_set_diag_color(lxw_format *self, lxw_color_t color)
-{
-    self->diag_color = lxw_format_check_color(color);
-}
-
-/*
- * Set the diag_border property.
- */
-void
-format_set_diag_border(lxw_format *self, uint8_t style)
-{
-    self->diag_border = style;
-}
-
-/*
- * Set the num_format_index property.
- */
-void
-format_set_num_format_index(lxw_format *self, uint8_t value)
-{
-    self->num_format_index = value;
-}
-
-/*
- * Set the valign property.
- */
-void
-format_set_valign(lxw_format *self, uint8_t value)
-{
-    self->text_v_align = value;
-}
-
-/*
- * Set the reading_order property.
- */
-void
-format_set_reading_order(lxw_format *self, uint8_t value)
-{
-    self->reading_order = value;
-}
-
-/*
- * Set the font_family property.
- */
-void
-format_set_font_family(lxw_format *self, uint8_t value)
-{
-    self->font_family = value;
-}
-
-/*
- * Set the font_charset property.
- */
-void
-format_set_font_charset(lxw_format *self, uint8_t value)
-{
-    self->font_charset = value;
-}
-
-/*
- * Set the font_scheme property.
- */
-void
-format_set_font_scheme(lxw_format *self, const char *font_scheme)
-{
-    LXW_FORMAT_FIELD_COPY(self->font_scheme, font_scheme);
-}
-
-/*
- * Set the font_condense property.
- */
-void
-format_set_font_condense(lxw_format *self)
-{
-    self->font_condense = LXW_TRUE;
-}
-
-/*
- * Set the font_extend property.
- */
-void
-format_set_font_extend(lxw_format *self)
-{
-    self->font_extend = LXW_TRUE;
-}
-
-/*
- * Set the theme property.
- */
-void
-format_set_theme(lxw_format *self, uint8_t value)
-{
-    self->theme = value;
-}

+ 0 - 355
library/src/xmlwriter.c

@@ -1,355 +0,0 @@
-/*****************************************************************************
- * xmlwriter - A base library for libxlsxwriter libraries.
- *
- * Used in conjunction with the libxlsxwriter library.
- *
- * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "xlsxwriter/xmlwriter.h"
-
-#define LXW_AMP  "&amp;"
-#define LXW_LT   "&lt;"
-#define LXW_GT   "&gt;"
-#define LXW_QUOT "&quot;"
-
-/* Defines. */
-#define LXW_MAX_ENCODED_ATTRIBUTE_LENGTH (LXW_MAX_ATTRIBUTE_LENGTH*6)
-
-/* Forward declarations. */
-STATIC char *_escape_attributes(struct xml_attribute *attribute);
-
-char *lxw_escape_data(const char *data);
-
-STATIC void _fprint_escaped_attributes(FILE * xmlfile,
-                                       struct xml_attribute_list *attributes);
-
-STATIC void _fprint_escaped_data(FILE * xmlfile, const char *data);
-
-/*
- * Write the XML declaration.
- */
-void
-lxw_xml_declaration(FILE * xmlfile)
-{
-    fprintf(xmlfile, "<?xml version=\"1.0\" "
-            "encoding=\"UTF-8\" standalone=\"yes\"?>\n");
-}
-
-/*
- * Write an XML start tag with optional attributes.
- */
-void
-lxw_xml_start_tag(FILE * xmlfile,
-                  const char *tag, struct xml_attribute_list *attributes)
-{
-    fprintf(xmlfile, "<%s", tag);
-
-    _fprint_escaped_attributes(xmlfile, attributes);
-
-    fprintf(xmlfile, ">");
-}
-
-/*
- * Write an XML start tag with optional, unencoded, attributes.
- * This is a minor speed optimization for elements that don't need encoding.
- */
-void
-lxw_xml_start_tag_unencoded(FILE * xmlfile,
-                            const char *tag,
-                            struct xml_attribute_list *attributes)
-{
-    struct xml_attribute *attribute;
-
-    fprintf(xmlfile, "<%s", tag);
-
-    if (attributes) {
-        STAILQ_FOREACH(attribute, attributes, list_entries) {
-            fprintf(xmlfile, " %s=\"%s\"", attribute->key, attribute->value);
-        }
-    }
-
-    fprintf(xmlfile, ">");
-}
-
-/*
- * Write an XML end tag.
- */
-void
-lxw_xml_end_tag(FILE * xmlfile, const char *tag)
-{
-    fprintf(xmlfile, "</%s>", tag);
-}
-
-/*
- * Write an empty XML tag with optional attributes.
- */
-void
-lxw_xml_empty_tag(FILE * xmlfile,
-                  const char *tag, struct xml_attribute_list *attributes)
-{
-    fprintf(xmlfile, "<%s", tag);
-
-    _fprint_escaped_attributes(xmlfile, attributes);
-
-    fprintf(xmlfile, "/>");
-}
-
-/*
- * Write an XML start tag with optional, unencoded, attributes.
- * This is a minor speed optimization for elements that don't need encoding.
- */
-void
-lxw_xml_empty_tag_unencoded(FILE * xmlfile,
-                            const char *tag,
-                            struct xml_attribute_list *attributes)
-{
-    struct xml_attribute *attribute;
-
-    fprintf(xmlfile, "<%s", tag);
-
-    if (attributes) {
-        STAILQ_FOREACH(attribute, attributes, list_entries) {
-            fprintf(xmlfile, " %s=\"%s\"", attribute->key, attribute->value);
-        }
-    }
-
-    fprintf(xmlfile, "/>");
-}
-
-/*
- * Write an XML element containing data with optional attributes.
- */
-void
-lxw_xml_data_element(FILE * xmlfile,
-                     const char *tag,
-                     const char *data, struct xml_attribute_list *attributes)
-{
-    fprintf(xmlfile, "<%s", tag);
-
-    _fprint_escaped_attributes(xmlfile, attributes);
-
-    fprintf(xmlfile, ">");
-
-    _fprint_escaped_data(xmlfile, data);
-
-    fprintf(xmlfile, "</%s>", tag);
-}
-
-/*
- * Escape XML characters in attributes.
- */
-STATIC char *
-_escape_attributes(struct xml_attribute *attribute)
-{
-    char *encoded = (char *) calloc(LXW_MAX_ENCODED_ATTRIBUTE_LENGTH, 1);
-    char *p_encoded = encoded;
-    char *p_attr = attribute->value;
-
-    while (*p_attr) {
-        switch (*p_attr) {
-            case '&':
-                strncat(p_encoded, LXW_AMP, sizeof(LXW_AMP) - 1);
-                p_encoded += sizeof(LXW_AMP) - 1;
-                break;
-            case '<':
-                strncat(p_encoded, LXW_LT, sizeof(LXW_LT) - 1);
-                p_encoded += sizeof(LXW_LT) - 1;
-                break;
-            case '>':
-                strncat(p_encoded, LXW_GT, sizeof(LXW_GT) - 1);
-                p_encoded += sizeof(LXW_GT) - 1;
-                break;
-            case '"':
-                strncat(p_encoded, LXW_QUOT, sizeof(LXW_QUOT) - 1);
-                p_encoded += sizeof(LXW_QUOT) - 1;
-                break;
-            default:
-                *p_encoded = *p_attr;
-                p_encoded++;
-                break;
-        }
-        p_attr++;
-    }
-
-    return encoded;
-}
-
-/*
- * Escape XML characters in data sections of tags.
- * Note, this is different from _escape_attributes()
- * in that double quotes are not escaped by Excel.
- */
-char *
-lxw_escape_data(const char *data)
-{
-    size_t encoded_len = (strlen(data) * 5 + 1);
-
-    char *encoded = (char *) calloc(encoded_len, 1);
-    char *p_encoded = encoded;
-
-    while (*data) {
-        switch (*data) {
-            case '&':
-                strncat(p_encoded, LXW_AMP, sizeof(LXW_AMP) - 1);
-                p_encoded += sizeof(LXW_AMP) - 1;
-                break;
-            case '<':
-                strncat(p_encoded, LXW_LT, sizeof(LXW_LT) - 1);
-                p_encoded += sizeof(LXW_LT) - 1;
-                break;
-            case '>':
-                strncat(p_encoded, LXW_GT, sizeof(LXW_GT) - 1);
-                p_encoded += sizeof(LXW_GT) - 1;
-                break;
-            default:
-                *p_encoded = *data;
-                p_encoded++;
-                break;
-        }
-        data++;
-    }
-
-    return encoded;
-}
-
-/*
- * Escape control characters in strings with with _xHHHH_.
- */
-char *
-lxw_escape_control_characters(const char *string)
-{
-    size_t escape_len = sizeof("_xHHHH_") - 1;
-    size_t encoded_len = (strlen(string) * escape_len + 1);
-
-    char *encoded = (char *) calloc(encoded_len, 1);
-    char *p_encoded = encoded;
-
-    while (*string) {
-        switch (*string) {
-            case '\x01':
-            case '\x02':
-            case '\x03':
-            case '\x04':
-            case '\x05':
-            case '\x06':
-            case '\x07':
-            case '\x08':
-            case '\x0B':
-            case '\x0C':
-            case '\x0D':
-            case '\x0E':
-            case '\x0F':
-            case '\x10':
-            case '\x11':
-            case '\x12':
-            case '\x13':
-            case '\x14':
-            case '\x15':
-            case '\x16':
-            case '\x17':
-            case '\x18':
-            case '\x19':
-            case '\x1A':
-            case '\x1B':
-            case '\x1C':
-            case '\x1D':
-            case '\x1E':
-            case '\x1F':
-                lxw_snprintf(p_encoded, escape_len + 1, "_x%04X_", *string);
-                p_encoded += escape_len;
-                break;
-            default:
-                *p_encoded = *string;
-                p_encoded++;
-                break;
-        }
-        string++;
-    }
-
-    return encoded;
-}
-
-/* Write out escaped attributes. */
-STATIC void
-_fprint_escaped_attributes(FILE * xmlfile,
-                           struct xml_attribute_list *attributes)
-{
-    struct xml_attribute *attribute;
-
-    if (attributes) {
-        STAILQ_FOREACH(attribute, attributes, list_entries) {
-            fprintf(xmlfile, " %s=", attribute->key);
-
-            if (!strpbrk(attribute->value, "&<>\"")) {
-                fprintf(xmlfile, "\"%s\"", attribute->value);
-            }
-            else {
-                char *encoded = _escape_attributes(attribute);
-
-                if (encoded) {
-                    fprintf(xmlfile, "\"%s\"", encoded);
-
-                    free(encoded);
-                }
-            }
-        }
-    }
-}
-
-/* Write out escaped XML data. */
-STATIC void
-_fprint_escaped_data(FILE * xmlfile, const char *data)
-{
-    /* Escape the data section of the XML element. */
-    if (!strpbrk(data, "&<>")) {
-        fprintf(xmlfile, "%s", data);
-    }
-    else {
-        char *encoded = lxw_escape_data(data);
-        if (encoded) {
-            fprintf(xmlfile, "%s", encoded);
-            free(encoded);
-        }
-    }
-}
-
-/* Create a new string XML attribute. */
-struct xml_attribute *
-lxw_new_attribute_str(const char *key, const char *value)
-{
-    struct xml_attribute *attribute = malloc(sizeof(struct xml_attribute));
-
-    LXW_ATTRIBUTE_COPY(attribute->key, key);
-    LXW_ATTRIBUTE_COPY(attribute->value, value);
-
-    return attribute;
-}
-
-/* Create a new integer XML attribute. */
-struct xml_attribute *
-lxw_new_attribute_int(const char *key, uint32_t value)
-{
-    struct xml_attribute *attribute = malloc(sizeof(struct xml_attribute));
-
-    LXW_ATTRIBUTE_COPY(attribute->key, key);
-    lxw_snprintf(attribute->value, LXW_MAX_ATTRIBUTE_LENGTH, "%d", value);
-
-    return attribute;
-}
-
-/* Create a new double XML attribute. */
-struct xml_attribute *
-lxw_new_attribute_dbl(const char *key, double value)
-{
-    struct xml_attribute *attribute = malloc(sizeof(struct xml_attribute));
-
-    LXW_ATTRIBUTE_COPY(attribute->key, key);
-    lxw_sprintf_dbl(attribute->value, value);
-
-    return attribute;
-}

+ 0 - 5
library/third_party/minizip/README.txt

@@ -1,5 +0,0 @@
-The souce files in this directory are included in libxlsxwriter from the
-contrib/minizip/ directory of zlib-1.2.8.
-
-The files zip.h and ioapi.h have had a small number of comments modifed from
-C++ to C style to avoid warnings with -pedantic -ansi.

+ 0 - 131
library/third_party/minizip/crypt.h

@@ -1,131 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
-   Version 1.01e, February 12th, 2005
-
-   Copyright (C) 1998-2005 Gilles Vollant
-
-   This code is a modified version of crypting code in Infozip distribution
-
-   The encryption/decryption parts of this source code (as opposed to the
-   non-echoing password parts) were originally written in Europe.  The
-   whole source package can be freely distributed, including from the USA.
-   (Prior to January 2000, re-export from the US was a violation of US law.)
-
-   This encryption code is a direct transcription of the algorithm from
-   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
-   file (appnote.txt) is distributed with the PKZIP program (even in the
-   version without encryption capabilities).
-
-   If you don't need crypting in your application, just define symbols
-   NOCRYPT and NOUNCRYPT.
-
-   This code support the "Traditional PKWARE Encryption".
-
-   The new AES encryption added on Zip format by Winzip (see the page
-   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
-   Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
-{
-    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
-                     * unpredictable manner on 16-bit systems; not a problem
-                     * with any known compiler so far, though */
-
-    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
-    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
-{
-    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
-    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
-    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
-    {
-      register int keyshift = (int)((*(pkeys+1)) >> 24);
-      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
-    }
-    return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
-{
-    *(pkeys+0) = 305419896L;
-    *(pkeys+1) = 591751049L;
-    *(pkeys+2) = 878082192L;
-    while (*passwd != '\0') {
-        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
-        passwd++;
-    }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
-    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
-    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN  12
-   /* "last resort" source for second part of crypt seed pattern */
-#  ifndef ZCR_SEED2
-#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
-#  endif
-
-static int crypthead(const char* passwd,      /* password string */
-                     unsigned char* buf,      /* where to write header */
-                     int bufSize,
-                     unsigned long* pkeys,
-                     const z_crc_t* pcrc_32_tab,
-                     unsigned long crcForCrypting)
-{
-    int n;                       /* index in random header */
-    int t;                       /* temporary */
-    int c;                       /* random byte */
-    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
-    static unsigned calls = 0;   /* ensure different random header each time */
-
-    if (bufSize<RAND_HEAD_LEN)
-      return 0;
-
-    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
-     * output of rand() to get less predictability, since rand() is
-     * often poorly implemented.
-     */
-    if (++calls == 1)
-    {
-        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
-    }
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        c = (rand() >> 7) & 0xff;
-        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
-    }
-    /* Encrypt random header (last two bytes is high word of crc) */
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
-    }
-    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
-    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
-    return n;
-}
-
-#endif

+ 0 - 247
library/third_party/minizip/ioapi.c

@@ -1,247 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-*/
-
-#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
-        #define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#if defined(__APPLE__) || defined(IOAPI_NO_64)
-// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
-#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
-#define FTELLO_FUNC(stream) ftello(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
-#else
-#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
-#define FTELLO_FUNC(stream) ftello64(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
-#endif
-
-
-#include "ioapi.h"
-
-voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
-{
-    if (pfilefunc->zfile_func64.zopen64_file != NULL)
-        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
-    else
-    {
-        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
-    }
-}
-
-long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
-{
-    if (pfilefunc->zfile_func64.zseek64_file != NULL)
-        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
-    else
-    {
-        uLong offsetTruncated = (uLong)offset;
-        if (offsetTruncated != offset)
-            return -1;
-        else
-            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
-    }
-}
-
-ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
-{
-    if (pfilefunc->zfile_func64.zseek64_file != NULL)
-        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
-    else
-    {
-        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
-        if ((tell_uLong) == MAXU32)
-            return (ZPOS64_T)-1;
-        else
-            return tell_uLong;
-    }
-}
-
-void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
-{
-    p_filefunc64_32->zfile_func64.zopen64_file = NULL;
-    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
-    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
-    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
-    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
-    p_filefunc64_32->zfile_func64.ztell64_file = NULL;
-    p_filefunc64_32->zfile_func64.zseek64_file = NULL;
-    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
-    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
-    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
-    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
-    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
-}
-
-
-
-static voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
-static uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-static uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
-static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
-static long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-static int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
-static int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
-
-static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
-{
-    FILE* file = NULL;
-    const char* mode_fopen = NULL;
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-        mode_fopen = "rb";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-        mode_fopen = "r+b";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-        mode_fopen = "wb";
-
-    if ((filename!=NULL) && (mode_fopen != NULL))
-        file = fopen(filename, mode_fopen);
-    return file;
-}
-
-static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
-{
-    FILE* file = NULL;
-    const char* mode_fopen = NULL;
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-        mode_fopen = "rb";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-        mode_fopen = "r+b";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-        mode_fopen = "wb";
-
-    if ((filename!=NULL) && (mode_fopen != NULL))
-        file = FOPEN_FUNC((const char*)filename, mode_fopen);
-    return file;
-}
-
-
-static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
-{
-    uLong ret;
-    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
-    return ret;
-}
-
-static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
-{
-    uLong ret;
-    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
-    return ret;
-}
-
-static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
-{
-    long ret;
-    ret = ftell((FILE *)stream);
-    return ret;
-}
-
-
-static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
-{
-    ZPOS64_T ret;
-    ret = FTELLO_FUNC((FILE *)stream);
-    return ret;
-}
-
-static long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)
-{
-    int fseek_origin=0;
-    long ret;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        fseek_origin = SEEK_CUR;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        fseek_origin = SEEK_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        fseek_origin = SEEK_SET;
-        break;
-    default: return -1;
-    }
-    ret = 0;
-    if (fseek((FILE *)stream, offset, fseek_origin) != 0)
-        ret = -1;
-    return ret;
-}
-
-static long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)
-{
-    int fseek_origin=0;
-    long ret;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        fseek_origin = SEEK_CUR;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        fseek_origin = SEEK_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        fseek_origin = SEEK_SET;
-        break;
-    default: return -1;
-    }
-    ret = 0;
-
-    if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
-                        ret = -1;
-
-    return ret;
-}
-
-
-static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
-{
-    int ret;
-    ret = fclose((FILE *)stream);
-    return ret;
-}
-
-static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
-{
-    int ret;
-    ret = ferror((FILE *)stream);
-    return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
-  zlib_filefunc_def* pzlib_filefunc_def;
-{
-    pzlib_filefunc_def->zopen_file = fopen_file_func;
-    pzlib_filefunc_def->zread_file = fread_file_func;
-    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
-    pzlib_filefunc_def->ztell_file = ftell_file_func;
-    pzlib_filefunc_def->zseek_file = fseek_file_func;
-    pzlib_filefunc_def->zclose_file = fclose_file_func;
-    pzlib_filefunc_def->zerror_file = ferror_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
-
-void fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)
-{
-    pzlib_filefunc_def->zopen64_file = fopen64_file_func;
-    pzlib_filefunc_def->zread_file = fread_file_func;
-    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
-    pzlib_filefunc_def->ztell64_file = ftell64_file_func;
-    pzlib_filefunc_def->zseek64_file = fseek64_file_func;
-    pzlib_filefunc_def->zclose_file = fclose_file_func;
-    pzlib_filefunc_def->zerror_file = ferror_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}

+ 0 - 208
library/third_party/minizip/ioapi.h

@@ -1,208 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         Changes
-
-    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
-    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
-               More if/def section may be needed to support other platforms
-    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
-                          (but you should use iowin32.c for windows instead)
-
-*/
-
-#ifndef _ZLIBIOAPI64_H
-#define _ZLIBIOAPI64_H
-
-#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
-
-  // Linux needs this to support file operation on files larger then 4+GB
-  // But might need better if/def to select just the platforms that needs them.
-
-        #ifndef __USE_FILE_OFFSET64
-                #define __USE_FILE_OFFSET64
-        #endif
-        #ifndef __USE_LARGEFILE64
-                #define __USE_LARGEFILE64
-        #endif
-        #ifndef _LARGEFILE64_SOURCE
-                #define _LARGEFILE64_SOURCE
-        #endif
-        #ifndef _FILE_OFFSET_BIT
-                #define _FILE_OFFSET_BIT 64
-        #endif
-
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "zlib.h"
-
-#if defined(USE_FILE32API)
-#define fopen64 fopen
-#define ftello64 ftell
-#define fseeko64 fseek
-#else
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#define fopen64 fopen
-#define ftello64 ftello
-#define fseeko64 fseeko
-#endif
-#ifdef _MSC_VER
- #define fopen64 fopen
- #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
-  #define ftello64 _ftelli64
-  #define fseeko64 _fseeki64
- #else // old MSC
-  #define ftello64 ftell
-  #define fseeko64 fseek
- #endif
-#endif
-#endif
-
-/*
-#ifndef ZPOS64_T
-  #ifdef _WIN32
-                #define ZPOS64_T fpos_t
-  #else
-    #include <stdint.h>
-    #define ZPOS64_T uint64_t
-  #endif
-#endif
-*/
-
-#ifdef HAVE_MINIZIP64_CONF_H
-#include "mz64conf.h"
-#endif
-
-/* a type choosen by DEFINE */
-#ifdef HAVE_64BIT_INT_CUSTOM
-typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
-#else
-#ifdef HAS_STDINT_H
-#include "stdint.h"
-typedef uint64_t ZPOS64_T;
-#else
-
-/* Maximum unsigned 32-bit value used as placeholder for zip64 */
-#define MAXU32 0xffffffff
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 ZPOS64_T;
-#else
-typedef unsigned long long int ZPOS64_T;
-#endif
-#endif
-#endif
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ      (1)
-#define ZLIB_FILEFUNC_MODE_WRITE     (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE   (8)
-
-
-#ifndef ZCALLBACK
- #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-   #define ZCALLBACK CALLBACK
- #else
-   #define ZCALLBACK
- #endif
-#endif
-
-
-
-
-typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
-typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
-typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-
-
-/* here is the "old" 32 bits structure structure */
-typedef struct zlib_filefunc_def_s
-{
-    open_file_func      zopen_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell_file_func      ztell_file;
-    seek_file_func      zseek_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc_def;
-
-typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
-
-typedef struct zlib_filefunc64_def_s
-{
-    open64_file_func    zopen64_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell64_file_func    ztell64_file;
-    seek64_file_func    zseek64_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc64_def;
-
-void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-/* now internal definition, only for zip.c and unzip.h */
-typedef struct zlib_filefunc64_32_def_s
-{
-    zlib_filefunc64_def zfile_func64;
-    open_file_func      zopen32_file;
-    tell_file_func      ztell32_file;
-    seek_file_func      zseek32_file;
-} zlib_filefunc64_32_def;
-
-
-#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
-#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
-/* #define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) */
-/* #define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) */
-#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
-#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
-
-voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
-long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
-ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
-
-void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
-
-#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
-#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
-#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 456
library/third_party/minizip/iowin32.c

@@ -1,456 +0,0 @@
-/* iowin32.c -- IO base function header for compress/uncompress .zip
-     Version 1.1, February 14h, 2010
-     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-     For more info read MiniZip_info.txt
-
-*/
-
-#include <stdlib.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-#include "iowin32.h"
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
-#endif
-
-#ifndef INVALID_SET_FILE_POINTER
-#define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-
-
-voidpf  ZCALLBACK win32_open_file_func  OF((voidpf opaque, const char* filename, int mode));
-uLong   ZCALLBACK win32_read_file_func  OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-uLong   ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-ZPOS64_T ZCALLBACK win32_tell64_file_func  OF((voidpf opaque, voidpf stream));
-long    ZCALLBACK win32_seek64_file_func  OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-int     ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));
-int     ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));
-
-typedef struct
-{
-    HANDLE hf;
-    int error;
-} WIN32FILE_IOWIN;
-
-
-static void win32_translate_open_mode(int mode,
-                                      DWORD* lpdwDesiredAccess,
-                                      DWORD* lpdwCreationDisposition,
-                                      DWORD* lpdwShareMode,
-                                      DWORD* lpdwFlagsAndAttributes)
-{
-    *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
-
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-    {
-        *lpdwDesiredAccess = GENERIC_READ;
-        *lpdwCreationDisposition = OPEN_EXISTING;
-        *lpdwShareMode = FILE_SHARE_READ;
-    }
-    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-    {
-        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
-        *lpdwCreationDisposition = OPEN_EXISTING;
-    }
-    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-    {
-        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
-        *lpdwCreationDisposition = CREATE_ALWAYS;
-    }
-}
-
-static voidpf win32_build_iowin(HANDLE hFile)
-{
-    voidpf ret=NULL;
-
-    if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
-    {
-        WIN32FILE_IOWIN w32fiow;
-        w32fiow.hf = hFile;
-        w32fiow.error = 0;
-        ret = malloc(sizeof(WIN32FILE_IOWIN));
-
-        if (ret==NULL)
-            CloseHandle(hFile);
-        else
-            *((WIN32FILE_IOWIN*)ret) = w32fiow;
-    }
-    return ret;
-}
-
-voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
-{
-    const char* mode_fopen = NULL;
-    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
-    HANDLE hFile = NULL;
-
-    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
-
-#ifdef IOWIN32_USING_WINRT_API
-#ifdef UNICODE
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
-#else
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-    {
-        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
-        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
-        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
-    }
-#endif
-#else
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
-#endif
-
-    return win32_build_iowin(hFile);
-}
-
-
-voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)
-{
-    const char* mode_fopen = NULL;
-    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
-    HANDLE hFile = NULL;
-
-    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
-
-#ifdef IOWIN32_USING_WINRT_API
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-    {
-        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
-        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
-        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
-    }
-#else
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
-#endif
-
-    return win32_build_iowin(hFile);
-}
-
-
-voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)
-{
-    const char* mode_fopen = NULL;
-    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
-    HANDLE hFile = NULL;
-
-    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
-
-#ifdef IOWIN32_USING_WINRT_API
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);
-#else
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
-#endif
-
-    return win32_build_iowin(hFile);
-}
-
-
-voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
-{
-    const char* mode_fopen = NULL;
-    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
-    HANDLE hFile = NULL;
-
-    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
-
-#ifdef IOWIN32_USING_WINRT_API
-#ifdef UNICODE
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
-#else
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-    {
-        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
-        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
-        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
-    }
-#endif
-#else
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
-#endif
-
-    return win32_build_iowin(hFile);
-}
-
-
-uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
-{
-    uLong ret=0;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-
-    if (hFile != NULL)
-    {
-        if (!ReadFile(hFile, buf, size, &ret, NULL))
-        {
-            DWORD dwErr = GetLastError();
-            if (dwErr == ERROR_HANDLE_EOF)
-                dwErr = 0;
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-        }
-    }
-
-    return ret;
-}
-
-
-uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)
-{
-    uLong ret=0;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-
-    if (hFile != NULL)
-    {
-        if (!WriteFile(hFile, buf, size, &ret, NULL))
-        {
-            DWORD dwErr = GetLastError();
-            if (dwErr == ERROR_HANDLE_EOF)
-                dwErr = 0;
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-        }
-    }
-
-    return ret;
-}
-
-static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos,  DWORD dwMoveMethod)
-{
-#ifdef IOWIN32_USING_WINRT_API
-    return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
-#else
-    LONG lHigh = pos.HighPart;
-    DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod);
-    BOOL fOk = TRUE;
-    if (dwNewPos == 0xFFFFFFFF)
-        if (GetLastError() != NO_ERROR)
-            fOk = FALSE;
-    if ((newPos != NULL) && (fOk))
-    {
-        newPos->LowPart = dwNewPos;
-        newPos->HighPart = lHigh;
-    }
-    return fOk;
-#endif
-}
-
-long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
-{
-    long ret=-1;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-    if (hFile != NULL)
-    {
-        LARGE_INTEGER pos;
-        pos.QuadPart = 0;
-
-        if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
-        {
-            DWORD dwErr = GetLastError();
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-            ret = -1;
-        }
-        else
-            ret=(long)pos.LowPart;
-    }
-    return ret;
-}
-
-ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
-{
-    ZPOS64_T ret= (ZPOS64_T)-1;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream)->hf;
-
-    if (hFile)
-    {
-        LARGE_INTEGER pos;
-        pos.QuadPart = 0;
-
-        if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
-        {
-            DWORD dwErr = GetLastError();
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-            ret = (ZPOS64_T)-1;
-        }
-        else
-            ret=pos.QuadPart;
-    }
-    return ret;
-}
-
-
-long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)
-{
-    DWORD dwMoveMethod=0xFFFFFFFF;
-    HANDLE hFile = NULL;
-
-    long ret=-1;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        dwMoveMethod = FILE_CURRENT;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        dwMoveMethod = FILE_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        dwMoveMethod = FILE_BEGIN;
-        break;
-    default: return -1;
-    }
-
-    if (hFile != NULL)
-    {
-        LARGE_INTEGER pos;
-        pos.QuadPart = offset;
-        if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
-        {
-            DWORD dwErr = GetLastError();
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-            ret = -1;
-        }
-        else
-            ret=0;
-    }
-    return ret;
-}
-
-long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)
-{
-    DWORD dwMoveMethod=0xFFFFFFFF;
-    HANDLE hFile = NULL;
-    long ret=-1;
-
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream)->hf;
-
-    switch (origin)
-    {
-        case ZLIB_FILEFUNC_SEEK_CUR :
-            dwMoveMethod = FILE_CURRENT;
-            break;
-        case ZLIB_FILEFUNC_SEEK_END :
-            dwMoveMethod = FILE_END;
-            break;
-        case ZLIB_FILEFUNC_SEEK_SET :
-            dwMoveMethod = FILE_BEGIN;
-            break;
-        default: return -1;
-    }
-
-    if (hFile)
-    {
-        LARGE_INTEGER pos;
-        pos.QuadPart = offset;
-        if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
-        {
-            DWORD dwErr = GetLastError();
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-            ret = -1;
-        }
-        else
-            ret=0;
-    }
-    return ret;
-}
-
-int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
-{
-    int ret=-1;
-
-    if (stream!=NULL)
-    {
-        HANDLE hFile;
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-        if (hFile != NULL)
-        {
-            CloseHandle(hFile);
-            ret=0;
-        }
-        free(stream);
-    }
-    return ret;
-}
-
-int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
-{
-    int ret=-1;
-    if (stream!=NULL)
-    {
-        ret = ((WIN32FILE_IOWIN*)stream) -> error;
-    }
-    return ret;
-}
-
-void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
-{
-    pzlib_filefunc_def->zopen_file = win32_open_file_func;
-    pzlib_filefunc_def->zread_file = win32_read_file_func;
-    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
-    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
-    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
-    pzlib_filefunc_def->zclose_file = win32_close_file_func;
-    pzlib_filefunc_def->zerror_file = win32_error_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
-
-void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
-{
-    pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
-    pzlib_filefunc_def->zread_file = win32_read_file_func;
-    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
-    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
-    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
-    pzlib_filefunc_def->zclose_file = win32_close_file_func;
-    pzlib_filefunc_def->zerror_file = win32_error_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
-
-
-void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
-{
-    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
-    pzlib_filefunc_def->zread_file = win32_read_file_func;
-    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
-    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
-    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
-    pzlib_filefunc_def->zclose_file = win32_close_file_func;
-    pzlib_filefunc_def->zerror_file = win32_error_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
-
-
-void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
-{
-    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
-    pzlib_filefunc_def->zread_file = win32_read_file_func;
-    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
-    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
-    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
-    pzlib_filefunc_def->zclose_file = win32_close_file_func;
-    pzlib_filefunc_def->zerror_file = win32_error_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}

+ 0 - 28
library/third_party/minizip/iowin32.h

@@ -1,28 +0,0 @@
-/* iowin32.h -- IO base function header for compress/uncompress .zip
-     Version 1.1, February 14h, 2010
-     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-*/
-
-#include <windows.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 7
library/third_party/minizip/iowin32.loT

@@ -1,7 +0,0 @@
-# library/third_party/minizip/iowin32.lo - a libtool object file
-# Generated by ltmain.sh - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# Name of the PIC object.

+ 0 - 660
library/third_party/minizip/miniunz.c

@@ -1,660 +0,0 @@
-/*
-   miniunz.c
-   Version 1.1, February 14h, 2010
-   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications of Unzip for Zip64
-         Copyright (C) 2007-2008 Even Rouault
-
-         Modifications for Zip64 support on both zip and unzip
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-*/
-
-#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
-        #ifndef __USE_FILE_OFFSET64
-                #define __USE_FILE_OFFSET64
-        #endif
-        #ifndef __USE_LARGEFILE64
-                #define __USE_LARGEFILE64
-        #endif
-        #ifndef _LARGEFILE64_SOURCE
-                #define _LARGEFILE64_SOURCE
-        #endif
-        #ifndef _FILE_OFFSET_BIT
-                #define _FILE_OFFSET_BIT 64
-        #endif
-#endif
-
-#ifdef __APPLE__
-// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
-#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
-#define FTELLO_FUNC(stream) ftello(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
-#else
-#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
-#define FTELLO_FUNC(stream) ftello64(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
-#endif
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-# include <direct.h>
-# include <io.h>
-#else
-# include <unistd.h>
-# include <utime.h>
-#endif
-
-
-#include "unzip.h"
-
-#define CASESENSITIVITY (0)
-#define WRITEBUFFERSIZE (8192)
-#define MAXFILENAME (256)
-
-#ifdef _WIN32
-#define USEWIN32IOAPI
-#include "iowin32.h"
-#endif
-/*
-  mini unzip, demo of unzip package
-
-  usage :
-  Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
-
-  list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
-    if it exists
-*/
-
-
-/* change_file_date : change the date/time of a file
-    filename : the filename of the file where date/time must be modified
-    dosdate : the new date at the MSDos format (4 bytes)
-    tmu_date : the SAME new date at the tm_unz format */
-void change_file_date(filename,dosdate,tmu_date)
-    const char *filename;
-    uLong dosdate;
-    tm_unz tmu_date;
-{
-#ifdef _WIN32
-  HANDLE hFile;
-  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
-
-  hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
-                      0,NULL,OPEN_EXISTING,0,NULL);
-  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
-  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
-  LocalFileTimeToFileTime(&ftLocal,&ftm);
-  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
-  CloseHandle(hFile);
-#else
-#ifdef unix || __APPLE__
-  struct utimbuf ut;
-  struct tm newdate;
-  newdate.tm_sec = tmu_date.tm_sec;
-  newdate.tm_min=tmu_date.tm_min;
-  newdate.tm_hour=tmu_date.tm_hour;
-  newdate.tm_mday=tmu_date.tm_mday;
-  newdate.tm_mon=tmu_date.tm_mon;
-  if (tmu_date.tm_year > 1900)
-      newdate.tm_year=tmu_date.tm_year - 1900;
-  else
-      newdate.tm_year=tmu_date.tm_year ;
-  newdate.tm_isdst=-1;
-
-  ut.actime=ut.modtime=mktime(&newdate);
-  utime(filename,&ut);
-#endif
-#endif
-}
-
-
-/* mymkdir and change_file_date are not 100 % portable
-   As I don't know well Unix, I wait feedback for the unix portion */
-
-int mymkdir(dirname)
-    const char* dirname;
-{
-    int ret=0;
-#ifdef _WIN32
-    ret = _mkdir(dirname);
-#elif unix
-    ret = mkdir (dirname,0775);
-#elif __APPLE__
-    ret = mkdir (dirname,0775);
-#endif
-    return ret;
-}
-
-int makedir (newdir)
-    char *newdir;
-{
-  char *buffer ;
-  char *p;
-  int  len = (int)strlen(newdir);
-
-  if (len <= 0)
-    return 0;
-
-  buffer = (char*)malloc(len+1);
-        if (buffer==NULL)
-        {
-                printf("Error allocating memory\n");
-                return UNZ_INTERNALERROR;
-        }
-  strcpy(buffer,newdir);
-
-  if (buffer[len-1] == '/') {
-    buffer[len-1] = '\0';
-  }
-  if (mymkdir(buffer) == 0)
-    {
-      free(buffer);
-      return 1;
-    }
-
-  p = buffer+1;
-  while (1)
-    {
-      char hold;
-
-      while(*p && *p != '\\' && *p != '/')
-        p++;
-      hold = *p;
-      *p = 0;
-      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
-        {
-          printf("couldn't create directory %s\n",buffer);
-          free(buffer);
-          return 0;
-        }
-      if (hold == 0)
-        break;
-      *p++ = hold;
-    }
-  free(buffer);
-  return 1;
-}
-
-void do_banner()
-{
-    printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
-    printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
-}
-
-void do_help()
-{
-    printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
-           "  -e  Extract without pathname (junk paths)\n" \
-           "  -x  Extract with pathname\n" \
-           "  -v  list files\n" \
-           "  -l  list files\n" \
-           "  -d  directory to extract into\n" \
-           "  -o  overwrite files without prompting\n" \
-           "  -p  extract crypted file using password\n\n");
-}
-
-void Display64BitsSize(ZPOS64_T n, int size_char)
-{
-  /* to avoid compatibility problem , we do here the conversion */
-  char number[21];
-  int offset=19;
-  int pos_string = 19;
-  number[20]=0;
-  for (;;) {
-      number[offset]=(char)((n%10)+'0');
-      if (number[offset] != '0')
-          pos_string=offset;
-      n/=10;
-      if (offset==0)
-          break;
-      offset--;
-  }
-  {
-      int size_display_string = 19-pos_string;
-      while (size_char > size_display_string)
-      {
-          size_char--;
-          printf(" ");
-      }
-  }
-
-  printf("%s",&number[pos_string]);
-}
-
-int do_list(uf)
-    unzFile uf;
-{
-    uLong i;
-    unz_global_info64 gi;
-    int err;
-
-    err = unzGetGlobalInfo64(uf,&gi);
-    if (err!=UNZ_OK)
-        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
-    printf("  Length  Method     Size Ratio   Date    Time   CRC-32     Name\n");
-    printf("  ------  ------     ---- -----   ----    ----   ------     ----\n");
-    for (i=0;i<gi.number_entry;i++)
-    {
-        char filename_inzip[256];
-        unz_file_info64 file_info;
-        uLong ratio=0;
-        const char *string_method;
-        char charCrypt=' ';
-        err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-        if (err!=UNZ_OK)
-        {
-            printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
-            break;
-        }
-        if (file_info.uncompressed_size>0)
-            ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
-
-        /* display a '*' if the file is crypted */
-        if ((file_info.flag & 1) != 0)
-            charCrypt='*';
-
-        if (file_info.compression_method==0)
-            string_method="Stored";
-        else
-        if (file_info.compression_method==Z_DEFLATED)
-        {
-            uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
-            if (iLevel==0)
-              string_method="Defl:N";
-            else if (iLevel==1)
-              string_method="Defl:X";
-            else if ((iLevel==2) || (iLevel==3))
-              string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
-        }
-        else
-        if (file_info.compression_method==Z_BZIP2ED)
-        {
-              string_method="BZip2 ";
-        }
-        else
-            string_method="Unkn. ";
-
-        Display64BitsSize(file_info.uncompressed_size,7);
-        printf("  %6s%c",string_method,charCrypt);
-        Display64BitsSize(file_info.compressed_size,7);
-        printf(" %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",
-                ratio,
-                (uLong)file_info.tmu_date.tm_mon + 1,
-                (uLong)file_info.tmu_date.tm_mday,
-                (uLong)file_info.tmu_date.tm_year % 100,
-                (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
-                (uLong)file_info.crc,filename_inzip);
-        if ((i+1)<gi.number_entry)
-        {
-            err = unzGoToNextFile(uf);
-            if (err!=UNZ_OK)
-            {
-                printf("error %d with zipfile in unzGoToNextFile\n",err);
-                break;
-            }
-        }
-    }
-
-    return 0;
-}
-
-
-int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
-    unzFile uf;
-    const int* popt_extract_without_path;
-    int* popt_overwrite;
-    const char* password;
-{
-    char filename_inzip[256];
-    char* filename_withoutpath;
-    char* p;
-    int err=UNZ_OK;
-    FILE *fout=NULL;
-    void* buf;
-    uInt size_buf;
-
-    unz_file_info64 file_info;
-    uLong ratio=0;
-    err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-
-    if (err!=UNZ_OK)
-    {
-        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
-        return err;
-    }
-
-    size_buf = WRITEBUFFERSIZE;
-    buf = (void*)malloc(size_buf);
-    if (buf==NULL)
-    {
-        printf("Error allocating memory\n");
-        return UNZ_INTERNALERROR;
-    }
-
-    p = filename_withoutpath = filename_inzip;
-    while ((*p) != '\0')
-    {
-        if (((*p)=='/') || ((*p)=='\\'))
-            filename_withoutpath = p+1;
-        p++;
-    }
-
-    if ((*filename_withoutpath)=='\0')
-    {
-        if ((*popt_extract_without_path)==0)
-        {
-            printf("creating directory: %s\n",filename_inzip);
-            mymkdir(filename_inzip);
-        }
-    }
-    else
-    {
-        const char* write_filename;
-        int skip=0;
-
-        if ((*popt_extract_without_path)==0)
-            write_filename = filename_inzip;
-        else
-            write_filename = filename_withoutpath;
-
-        err = unzOpenCurrentFilePassword(uf,password);
-        if (err!=UNZ_OK)
-        {
-            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
-        }
-
-        if (((*popt_overwrite)==0) && (err==UNZ_OK))
-        {
-            char rep=0;
-            FILE* ftestexist;
-            ftestexist = FOPEN_FUNC(write_filename,"rb");
-            if (ftestexist!=NULL)
-            {
-                fclose(ftestexist);
-                do
-                {
-                    char answer[128];
-                    int ret;
-
-                    printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
-                    ret = scanf("%1s",answer);
-                    if (ret != 1)
-                    {
-                       exit(EXIT_FAILURE);
-                    }
-                    rep = answer[0] ;
-                    if ((rep>='a') && (rep<='z'))
-                        rep -= 0x20;
-                }
-                while ((rep!='Y') && (rep!='N') && (rep!='A'));
-            }
-
-            if (rep == 'N')
-                skip = 1;
-
-            if (rep == 'A')
-                *popt_overwrite=1;
-        }
-
-        if ((skip==0) && (err==UNZ_OK))
-        {
-            fout=FOPEN_FUNC(write_filename,"wb");
-            /* some zipfile don't contain directory alone before file */
-            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
-                                (filename_withoutpath!=(char*)filename_inzip))
-            {
-                char c=*(filename_withoutpath-1);
-                *(filename_withoutpath-1)='\0';
-                makedir(write_filename);
-                *(filename_withoutpath-1)=c;
-                fout=FOPEN_FUNC(write_filename,"wb");
-            }
-
-            if (fout==NULL)
-            {
-                printf("error opening %s\n",write_filename);
-            }
-        }
-
-        if (fout!=NULL)
-        {
-            printf(" extracting: %s\n",write_filename);
-
-            do
-            {
-                err = unzReadCurrentFile(uf,buf,size_buf);
-                if (err<0)
-                {
-                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
-                    break;
-                }
-                if (err>0)
-                    if (fwrite(buf,err,1,fout)!=1)
-                    {
-                        printf("error in writing extracted file\n");
-                        err=UNZ_ERRNO;
-                        break;
-                    }
-            }
-            while (err>0);
-            if (fout)
-                    fclose(fout);
-
-            if (err==0)
-                change_file_date(write_filename,file_info.dosDate,
-                                 file_info.tmu_date);
-        }
-
-        if (err==UNZ_OK)
-        {
-            err = unzCloseCurrentFile (uf);
-            if (err!=UNZ_OK)
-            {
-                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
-            }
-        }
-        else
-            unzCloseCurrentFile(uf); /* don't lose the error */
-    }
-
-    free(buf);
-    return err;
-}
-
-
-int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
-    unzFile uf;
-    int opt_extract_without_path;
-    int opt_overwrite;
-    const char* password;
-{
-    uLong i;
-    unz_global_info64 gi;
-    int err;
-    FILE* fout=NULL;
-
-    err = unzGetGlobalInfo64(uf,&gi);
-    if (err!=UNZ_OK)
-        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
-
-    for (i=0;i<gi.number_entry;i++)
-    {
-        if (do_extract_currentfile(uf,&opt_extract_without_path,
-                                      &opt_overwrite,
-                                      password) != UNZ_OK)
-            break;
-
-        if ((i+1)<gi.number_entry)
-        {
-            err = unzGoToNextFile(uf);
-            if (err!=UNZ_OK)
-            {
-                printf("error %d with zipfile in unzGoToNextFile\n",err);
-                break;
-            }
-        }
-    }
-
-    return 0;
-}
-
-int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
-    unzFile uf;
-    const char* filename;
-    int opt_extract_without_path;
-    int opt_overwrite;
-    const char* password;
-{
-    int err = UNZ_OK;
-    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
-    {
-        printf("file %s not found in the zipfile\n",filename);
-        return 2;
-    }
-
-    if (do_extract_currentfile(uf,&opt_extract_without_path,
-                                      &opt_overwrite,
-                                      password) == UNZ_OK)
-        return 0;
-    else
-        return 1;
-}
-
-
-int main(argc,argv)
-    int argc;
-    char *argv[];
-{
-    const char *zipfilename=NULL;
-    const char *filename_to_extract=NULL;
-    const char *password=NULL;
-    char filename_try[MAXFILENAME+16] = "";
-    int i;
-    int ret_value=0;
-    int opt_do_list=0;
-    int opt_do_extract=1;
-    int opt_do_extract_withoutpath=0;
-    int opt_overwrite=0;
-    int opt_extractdir=0;
-    const char *dirname=NULL;
-    unzFile uf=NULL;
-
-    do_banner();
-    if (argc==1)
-    {
-        do_help();
-        return 0;
-    }
-    else
-    {
-        for (i=1;i<argc;i++)
-        {
-            if ((*argv[i])=='-')
-            {
-                const char *p=argv[i]+1;
-
-                while ((*p)!='\0')
-                {
-                    char c=*(p++);;
-                    if ((c=='l') || (c=='L'))
-                        opt_do_list = 1;
-                    if ((c=='v') || (c=='V'))
-                        opt_do_list = 1;
-                    if ((c=='x') || (c=='X'))
-                        opt_do_extract = 1;
-                    if ((c=='e') || (c=='E'))
-                        opt_do_extract = opt_do_extract_withoutpath = 1;
-                    if ((c=='o') || (c=='O'))
-                        opt_overwrite=1;
-                    if ((c=='d') || (c=='D'))
-                    {
-                        opt_extractdir=1;
-                        dirname=argv[i+1];
-                    }
-
-                    if (((c=='p') || (c=='P')) && (i+1<argc))
-                    {
-                        password=argv[i+1];
-                        i++;
-                    }
-                }
-            }
-            else
-            {
-                if (zipfilename == NULL)
-                    zipfilename = argv[i];
-                else if ((filename_to_extract==NULL) && (!opt_extractdir))
-                        filename_to_extract = argv[i] ;
-            }
-        }
-    }
-
-    if (zipfilename!=NULL)
-    {
-
-#        ifdef USEWIN32IOAPI
-        zlib_filefunc64_def ffunc;
-#        endif
-
-        strncpy(filename_try, zipfilename,MAXFILENAME-1);
-        /* strncpy doesnt append the trailing NULL, of the string is too long. */
-        filename_try[ MAXFILENAME ] = '\0';
-
-#        ifdef USEWIN32IOAPI
-        fill_win32_filefunc64A(&ffunc);
-        uf = unzOpen2_64(zipfilename,&ffunc);
-#        else
-        uf = unzOpen64(zipfilename);
-#        endif
-        if (uf==NULL)
-        {
-            strcat(filename_try,".zip");
-#            ifdef USEWIN32IOAPI
-            uf = unzOpen2_64(filename_try,&ffunc);
-#            else
-            uf = unzOpen64(filename_try);
-#            endif
-        }
-    }
-
-    if (uf==NULL)
-    {
-        printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
-        return 1;
-    }
-    printf("%s opened\n",filename_try);
-
-    if (opt_do_list==1)
-        ret_value = do_list(uf);
-    else if (opt_do_extract==1)
-    {
-#ifdef _WIN32
-        if (opt_extractdir && _chdir(dirname))
-#else
-        if (opt_extractdir && chdir(dirname))
-#endif
-        {
-          printf("Error changing into %s, aborting\n", dirname);
-          exit(-1);
-        }
-
-        if (filename_to_extract == NULL)
-            ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
-        else
-            ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
-    }
-
-    unzClose(uf);
-
-    return ret_value;
-}

+ 0 - 520
library/third_party/minizip/minizip.c

@@ -1,520 +0,0 @@
-/*
-   minizip.c
-   Version 1.1, February 14h, 2010
-   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications of Unzip for Zip64
-         Copyright (C) 2007-2008 Even Rouault
-
-         Modifications for Zip64 support on both zip and unzip
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-*/
-
-
-#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
-        #ifndef __USE_FILE_OFFSET64
-                #define __USE_FILE_OFFSET64
-        #endif
-        #ifndef __USE_LARGEFILE64
-                #define __USE_LARGEFILE64
-        #endif
-        #ifndef _LARGEFILE64_SOURCE
-                #define _LARGEFILE64_SOURCE
-        #endif
-        #ifndef _FILE_OFFSET_BIT
-                #define _FILE_OFFSET_BIT 64
-        #endif
-#endif
-
-#ifdef __APPLE__
-// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
-#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
-#define FTELLO_FUNC(stream) ftello(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
-#else
-#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
-#define FTELLO_FUNC(stream) ftello64(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
-#endif
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-# include <direct.h>
-# include <io.h>
-#else
-# include <unistd.h>
-# include <utime.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-#endif
-
-#include "zip.h"
-
-#ifdef _WIN32
-        #define USEWIN32IOAPI
-        #include "iowin32.h"
-#endif
-
-
-
-#define WRITEBUFFERSIZE (16384)
-#define MAXFILENAME (256)
-
-#ifdef _WIN32
-uLong filetime(f, tmzip, dt)
-    char *f;                /* name of file to get info on */
-    tm_zip *tmzip;             /* return value: access, modific. and creation times */
-    uLong *dt;             /* dostime */
-{
-  int ret = 0;
-  {
-      FILETIME ftLocal;
-      HANDLE hFind;
-      WIN32_FIND_DATAA ff32;
-
-      hFind = FindFirstFileA(f,&ff32);
-      if (hFind != INVALID_HANDLE_VALUE)
-      {
-        FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
-        FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
-        FindClose(hFind);
-        ret = 1;
-      }
-  }
-  return ret;
-}
-#else
-#ifdef unix || __APPLE__
-uLong filetime(f, tmzip, dt)
-    char *f;               /* name of file to get info on */
-    tm_zip *tmzip;         /* return value: access, modific. and creation times */
-    uLong *dt;             /* dostime */
-{
-  int ret=0;
-  struct stat s;        /* results of stat() */
-  struct tm* filedate;
-  time_t tm_t=0;
-
-  if (strcmp(f,"-")!=0)
-  {
-    char name[MAXFILENAME+1];
-    int len = strlen(f);
-    if (len > MAXFILENAME)
-      len = MAXFILENAME;
-
-    strncpy(name, f,MAXFILENAME-1);
-    /* strncpy doesnt append the trailing NULL, of the string is too long. */
-    name[ MAXFILENAME ] = '\0';
-
-    if (name[len - 1] == '/')
-      name[len - 1] = '\0';
-    /* not all systems allow stat'ing a file with / appended */
-    if (stat(name,&s)==0)
-    {
-      tm_t = s.st_mtime;
-      ret = 1;
-    }
-  }
-  filedate = localtime(&tm_t);
-
-  tmzip->tm_sec  = filedate->tm_sec;
-  tmzip->tm_min  = filedate->tm_min;
-  tmzip->tm_hour = filedate->tm_hour;
-  tmzip->tm_mday = filedate->tm_mday;
-  tmzip->tm_mon  = filedate->tm_mon ;
-  tmzip->tm_year = filedate->tm_year;
-
-  return ret;
-}
-#else
-uLong filetime(f, tmzip, dt)
-    char *f;                /* name of file to get info on */
-    tm_zip *tmzip;             /* return value: access, modific. and creation times */
-    uLong *dt;             /* dostime */
-{
-    return 0;
-}
-#endif
-#endif
-
-
-
-
-int check_exist_file(filename)
-    const char* filename;
-{
-    FILE* ftestexist;
-    int ret = 1;
-    ftestexist = FOPEN_FUNC(filename,"rb");
-    if (ftestexist==NULL)
-        ret = 0;
-    else
-        fclose(ftestexist);
-    return ret;
-}
-
-void do_banner()
-{
-    printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
-    printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
-}
-
-void do_help()
-{
-    printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
-           "  -o  Overwrite existing file.zip\n" \
-           "  -a  Append to existing file.zip\n" \
-           "  -0  Store only\n" \
-           "  -1  Compress faster\n" \
-           "  -9  Compress better\n\n" \
-           "  -j  exclude path. store only the file name.\n\n");
-}
-
-/* calculate the CRC32 of a file,
-   because to encrypt a file, we need known the CRC32 of the file before */
-int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
-{
-   unsigned long calculate_crc=0;
-   int err=ZIP_OK;
-   FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
-
-   unsigned long size_read = 0;
-   unsigned long total_read = 0;
-   if (fin==NULL)
-   {
-       err = ZIP_ERRNO;
-   }
-
-    if (err == ZIP_OK)
-        do
-        {
-            err = ZIP_OK;
-            size_read = (int)fread(buf,1,size_buf,fin);
-            if (size_read < size_buf)
-                if (feof(fin)==0)
-            {
-                printf("error in reading %s\n",filenameinzip);
-                err = ZIP_ERRNO;
-            }
-
-            if (size_read>0)
-                calculate_crc = crc32(calculate_crc,buf,size_read);
-            total_read += size_read;
-
-        } while ((err == ZIP_OK) && (size_read>0));
-
-    if (fin)
-        fclose(fin);
-
-    *result_crc=calculate_crc;
-    printf("file %s crc %lx\n", filenameinzip, calculate_crc);
-    return err;
-}
-
-int isLargeFile(const char* filename)
-{
-  int largeFile = 0;
-  ZPOS64_T pos = 0;
-  FILE* pFile = FOPEN_FUNC(filename, "rb");
-
-  if(pFile != NULL)
-  {
-    int n = FSEEKO_FUNC(pFile, 0, SEEK_END);
-    pos = FTELLO_FUNC(pFile);
-
-                printf("File : %s is %lld bytes\n", filename, pos);
-
-    if(pos >= 0xffffffff)
-     largeFile = 1;
-
-                fclose(pFile);
-  }
-
- return largeFile;
-}
-
-int main(argc,argv)
-    int argc;
-    char *argv[];
-{
-    int i;
-    int opt_overwrite=0;
-    int opt_compress_level=Z_DEFAULT_COMPRESSION;
-    int opt_exclude_path=0;
-    int zipfilenamearg = 0;
-    char filename_try[MAXFILENAME+16];
-    int zipok;
-    int err=0;
-    int size_buf=0;
-    void* buf=NULL;
-    const char* password=NULL;
-
-
-    do_banner();
-    if (argc==1)
-    {
-        do_help();
-        return 0;
-    }
-    else
-    {
-        for (i=1;i<argc;i++)
-        {
-            if ((*argv[i])=='-')
-            {
-                const char *p=argv[i]+1;
-
-                while ((*p)!='\0')
-                {
-                    char c=*(p++);;
-                    if ((c=='o') || (c=='O'))
-                        opt_overwrite = 1;
-                    if ((c=='a') || (c=='A'))
-                        opt_overwrite = 2;
-                    if ((c>='0') && (c<='9'))
-                        opt_compress_level = c-'0';
-                    if ((c=='j') || (c=='J'))
-                        opt_exclude_path = 1;
-
-                    if (((c=='p') || (c=='P')) && (i+1<argc))
-                    {
-                        password=argv[i+1];
-                        i++;
-                    }
-                }
-            }
-            else
-            {
-                if (zipfilenamearg == 0)
-                {
-                    zipfilenamearg = i ;
-                }
-            }
-        }
-    }
-
-    size_buf = WRITEBUFFERSIZE;
-    buf = (void*)malloc(size_buf);
-    if (buf==NULL)
-    {
-        printf("Error allocating memory\n");
-        return ZIP_INTERNALERROR;
-    }
-
-    if (zipfilenamearg==0)
-    {
-        zipok=0;
-    }
-    else
-    {
-        int i,len;
-        int dot_found=0;
-
-        zipok = 1 ;
-        strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
-        /* strncpy doesnt append the trailing NULL, of the string is too long. */
-        filename_try[ MAXFILENAME ] = '\0';
-
-        len=(int)strlen(filename_try);
-        for (i=0;i<len;i++)
-            if (filename_try[i]=='.')
-                dot_found=1;
-
-        if (dot_found==0)
-            strcat(filename_try,".zip");
-
-        if (opt_overwrite==2)
-        {
-            /* if the file don't exist, we not append file */
-            if (check_exist_file(filename_try)==0)
-                opt_overwrite=1;
-        }
-        else
-        if (opt_overwrite==0)
-            if (check_exist_file(filename_try)!=0)
-            {
-                char rep=0;
-                do
-                {
-                    char answer[128];
-                    int ret;
-                    printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
-                    ret = scanf("%1s",answer);
-                    if (ret != 1)
-                    {
-                       exit(EXIT_FAILURE);
-                    }
-                    rep = answer[0] ;
-                    if ((rep>='a') && (rep<='z'))
-                        rep -= 0x20;
-                }
-                while ((rep!='Y') && (rep!='N') && (rep!='A'));
-                if (rep=='N')
-                    zipok = 0;
-                if (rep=='A')
-                    opt_overwrite = 2;
-            }
-    }
-
-    if (zipok==1)
-    {
-        zipFile zf;
-        int errclose;
-#        ifdef USEWIN32IOAPI
-        zlib_filefunc64_def ffunc;
-        fill_win32_filefunc64A(&ffunc);
-        zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
-#        else
-        zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
-#        endif
-
-        if (zf == NULL)
-        {
-            printf("error opening %s\n",filename_try);
-            err= ZIP_ERRNO;
-        }
-        else
-            printf("creating %s\n",filename_try);
-
-        for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
-        {
-            if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
-                  ((argv[i][1]=='o') || (argv[i][1]=='O') ||
-                   (argv[i][1]=='a') || (argv[i][1]=='A') ||
-                   (argv[i][1]=='p') || (argv[i][1]=='P') ||
-                   ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
-                  (strlen(argv[i]) == 2)))
-            {
-                FILE * fin;
-                int size_read;
-                const char* filenameinzip = argv[i];
-                const char *savefilenameinzip;
-                zip_fileinfo zi;
-                unsigned long crcFile=0;
-                int zip64 = 0;
-
-                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
-                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
-                zi.dosDate = 0;
-                zi.internal_fa = 0;
-                zi.external_fa = 0;
-                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
-
-/*
-                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
-                                 NULL,0,NULL,0,NULL / * comment * /,
-                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
-                                 opt_compress_level);
-*/
-                if ((password != NULL) && (err==ZIP_OK))
-                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
-
-                zip64 = isLargeFile(filenameinzip);
-
-                                                         /* The path name saved, should not include a leading slash. */
-               /*if it did, windows/xp and dynazip couldn't read the zip file. */
-                 savefilenameinzip = filenameinzip;
-                 while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
-                 {
-                     savefilenameinzip++;
-                 }
-
-                 /*should the zip file contain any path at all?*/
-                 if( opt_exclude_path )
-                 {
-                     const char *tmpptr;
-                     const char *lastslash = 0;
-                     for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
-                     {
-                         if( *tmpptr == '\\' || *tmpptr == '/')
-                         {
-                             lastslash = tmpptr;
-                         }
-                     }
-                     if( lastslash != NULL )
-                     {
-                         savefilenameinzip = lastslash+1; // base filename follows last slash.
-                     }
-                 }
-
-                 /**/
-                err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
-                                 NULL,0,NULL,0,NULL /* comment*/,
-                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
-                                 opt_compress_level,0,
-                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 password,crcFile, zip64);
-
-                if (err != ZIP_OK)
-                    printf("error in opening %s in zipfile\n",filenameinzip);
-                else
-                {
-                    fin = FOPEN_FUNC(filenameinzip,"rb");
-                    if (fin==NULL)
-                    {
-                        err=ZIP_ERRNO;
-                        printf("error in opening %s for reading\n",filenameinzip);
-                    }
-                }
-
-                if (err == ZIP_OK)
-                    do
-                    {
-                        err = ZIP_OK;
-                        size_read = (int)fread(buf,1,size_buf,fin);
-                        if (size_read < size_buf)
-                            if (feof(fin)==0)
-                        {
-                            printf("error in reading %s\n",filenameinzip);
-                            err = ZIP_ERRNO;
-                        }
-
-                        if (size_read>0)
-                        {
-                            err = zipWriteInFileInZip (zf,buf,size_read);
-                            if (err<0)
-                            {
-                                printf("error in writing %s in the zipfile\n",
-                                                 filenameinzip);
-                            }
-
-                        }
-                    } while ((err == ZIP_OK) && (size_read>0));
-
-                if (fin)
-                    fclose(fin);
-
-                if (err<0)
-                    err=ZIP_ERRNO;
-                else
-                {
-                    err = zipCloseFileInZip(zf);
-                    if (err!=ZIP_OK)
-                        printf("error in closing %s in the zipfile\n",
-                                    filenameinzip);
-                }
-            }
-        }
-        errclose = zipClose(zf,NULL);
-        if (errclose != ZIP_OK)
-            printf("error in closing %s\n",filename_try);
-    }
-    else
-    {
-       do_help();
-    }
-
-    free(buf);
-    return 0;
-}

+ 0 - 291
library/third_party/minizip/mztools.c

@@ -1,291 +0,0 @@
-/*
-  Additional tools for Minizip
-  Code: Xavier Roche '2004
-  License: Same as ZLIB (www.gzip.org)
-*/
-
-/* Code */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#define READ_8(adr)  ((unsigned char)*(adr))
-#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
-#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
-
-#define WRITE_8(buff, n) do { \
-  *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
-} while(0)
-#define WRITE_16(buff, n) do { \
-  WRITE_8((unsigned char*)(buff), n); \
-  WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
-} while(0)
-#define WRITE_32(buff, n) do { \
-  WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
-  WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
-} while(0)
-
-extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
-const char* file;
-const char* fileOut;
-const char* fileOutTmp;
-uLong* nRecovered;
-uLong* bytesRecovered;
-{
-  int err = Z_OK;
-  FILE* fpZip = fopen(file, "rb");
-  FILE* fpOut = fopen(fileOut, "wb");
-  FILE* fpOutCD = fopen(fileOutTmp, "wb");
-  if (fpZip != NULL &&  fpOut != NULL) {
-    int entries = 0;
-    uLong totalBytes = 0;
-    char header[30];
-    char filename[1024];
-    char extra[1024];
-    int offset = 0;
-    int offsetCD = 0;
-    while ( fread(header, 1, 30, fpZip) == 30 ) {
-      int currentOffset = offset;
-
-      /* File entry */
-      if (READ_32(header) == 0x04034b50) {
-        unsigned int version = READ_16(header + 4);
-        unsigned int gpflag = READ_16(header + 6);
-        unsigned int method = READ_16(header + 8);
-        unsigned int filetime = READ_16(header + 10);
-        unsigned int filedate = READ_16(header + 12);
-        unsigned int crc = READ_32(header + 14); /* crc */
-        unsigned int cpsize = READ_32(header + 18); /* compressed size */
-        unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
-        unsigned int fnsize = READ_16(header + 26); /* file name length */
-        unsigned int extsize = READ_16(header + 28); /* extra field length */
-        filename[0] = extra[0] = '\0';
-
-        /* Header */
-        if (fwrite(header, 1, 30, fpOut) == 30) {
-          offset += 30;
-        } else {
-          err = Z_ERRNO;
-          break;
-        }
-
-        /* Filename */
-        if (fnsize > 0) {
-          if (fnsize < sizeof(filename)) {
-            if (fread(filename, 1, fnsize, fpZip) == fnsize) {
-                if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
-                offset += fnsize;
-              } else {
-                err = Z_ERRNO;
-                break;
-              }
-            } else {
-              err = Z_ERRNO;
-              break;
-            }
-          } else {
-            err = Z_ERRNO;
-            break;
-          }
-        } else {
-          err = Z_STREAM_ERROR;
-          break;
-        }
-
-        /* Extra field */
-        if (extsize > 0) {
-          if (extsize < sizeof(extra)) {
-            if (fread(extra, 1, extsize, fpZip) == extsize) {
-              if (fwrite(extra, 1, extsize, fpOut) == extsize) {
-                offset += extsize;
-                } else {
-                err = Z_ERRNO;
-                break;
-              }
-            } else {
-              err = Z_ERRNO;
-              break;
-            }
-          } else {
-            err = Z_ERRNO;
-            break;
-          }
-        }
-
-        /* Data */
-        {
-          int dataSize = cpsize;
-          if (dataSize == 0) {
-            dataSize = uncpsize;
-          }
-          if (dataSize > 0) {
-            char* data = malloc(dataSize);
-            if (data != NULL) {
-              if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
-                if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
-                  offset += dataSize;
-                  totalBytes += dataSize;
-                } else {
-                  err = Z_ERRNO;
-                }
-              } else {
-                err = Z_ERRNO;
-              }
-              free(data);
-              if (err != Z_OK) {
-                break;
-              }
-            } else {
-              err = Z_MEM_ERROR;
-              break;
-            }
-          }
-        }
-
-        /* Central directory entry */
-        {
-          char header[46];
-          char* comment = "";
-          int comsize = (int) strlen(comment);
-          WRITE_32(header, 0x02014b50);
-          WRITE_16(header + 4, version);
-          WRITE_16(header + 6, version);
-          WRITE_16(header + 8, gpflag);
-          WRITE_16(header + 10, method);
-          WRITE_16(header + 12, filetime);
-          WRITE_16(header + 14, filedate);
-          WRITE_32(header + 16, crc);
-          WRITE_32(header + 20, cpsize);
-          WRITE_32(header + 24, uncpsize);
-          WRITE_16(header + 28, fnsize);
-          WRITE_16(header + 30, extsize);
-          WRITE_16(header + 32, comsize);
-          WRITE_16(header + 34, 0);     /* disk # */
-          WRITE_16(header + 36, 0);     /* int attrb */
-          WRITE_32(header + 38, 0);     /* ext attrb */
-          WRITE_32(header + 42, currentOffset);
-          /* Header */
-          if (fwrite(header, 1, 46, fpOutCD) == 46) {
-            offsetCD += 46;
-
-            /* Filename */
-            if (fnsize > 0) {
-              if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
-                offsetCD += fnsize;
-              } else {
-                err = Z_ERRNO;
-                break;
-              }
-            } else {
-              err = Z_STREAM_ERROR;
-              break;
-            }
-
-            /* Extra field */
-            if (extsize > 0) {
-              if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
-                offsetCD += extsize;
-              } else {
-                err = Z_ERRNO;
-                break;
-              }
-            }
-
-            /* Comment field */
-            if (comsize > 0) {
-              if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
-                offsetCD += comsize;
-              } else {
-                err = Z_ERRNO;
-                break;
-              }
-            }
-
-
-          } else {
-            err = Z_ERRNO;
-            break;
-          }
-        }
-
-        /* Success */
-        entries++;
-
-      } else {
-        break;
-      }
-    }
-
-    /* Final central directory  */
-    {
-      int entriesZip = entries;
-      char header[22];
-      char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
-      int comsize = (int) strlen(comment);
-      if (entriesZip > 0xffff) {
-        entriesZip = 0xffff;
-      }
-      WRITE_32(header, 0x06054b50);
-      WRITE_16(header + 4, 0);    /* disk # */
-      WRITE_16(header + 6, 0);    /* disk # */
-      WRITE_16(header + 8, entriesZip);   /* hack */
-      WRITE_16(header + 10, entriesZip);  /* hack */
-      WRITE_32(header + 12, offsetCD);    /* size of CD */
-      WRITE_32(header + 16, offset);      /* offset to CD */
-      WRITE_16(header + 20, comsize);     /* comment */
-
-      /* Header */
-      if (fwrite(header, 1, 22, fpOutCD) == 22) {
-
-        /* Comment field */
-        if (comsize > 0) {
-          if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
-            err = Z_ERRNO;
-          }
-        }
-
-      } else {
-        err = Z_ERRNO;
-      }
-    }
-
-    /* Final merge (file + central directory) */
-    fclose(fpOutCD);
-    if (err == Z_OK) {
-      fpOutCD = fopen(fileOutTmp, "rb");
-      if (fpOutCD != NULL) {
-        int nRead;
-        char buffer[8192];
-        while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
-          if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
-            err = Z_ERRNO;
-            break;
-          }
-        }
-        fclose(fpOutCD);
-      }
-    }
-
-    /* Close */
-    fclose(fpZip);
-    fclose(fpOut);
-
-    /* Wipe temporary file */
-    (void)remove(fileOutTmp);
-
-    /* Number of recovered entries */
-    if (err == Z_OK) {
-      if (nRecovered != NULL) {
-        *nRecovered = entries;
-      }
-      if (bytesRecovered != NULL) {
-        *bytesRecovered = totalBytes;
-      }
-    }
-  } else {
-    err = Z_STREAM_ERROR;
-  }
-  return err;
-}

+ 0 - 37
library/third_party/minizip/mztools.h

@@ -1,37 +0,0 @@
-/*
-  Additional tools for Minizip
-  Code: Xavier Roche '2004
-  License: Same as ZLIB (www.gzip.org)
-*/
-
-#ifndef _zip_tools_H
-#define _zip_tools_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#include "unzip.h"
-
-/* Repair a ZIP file (missing central directory)
-   file: file to recover
-   fileOut: output file after recovery
-   fileOutTmp: temporary file name used for recovery
-*/
-extern int ZEXPORT unzRepair(const char* file,
-                             const char* fileOut,
-                             const char* fileOutTmp,
-                             uLong* nRecovered,
-                             uLong* bytesRecovered);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif

+ 0 - 2125
library/third_party/minizip/unzip.c

@@ -1,2125 +0,0 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications of Unzip for Zip64
-         Copyright (C) 2007-2008 Even Rouault
-
-         Modifications for Zip64 support on both zip and unzip
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-
-  ------------------------------------------------------------------------------------
-  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-  compatibility with older software. The following is from the original crypt.c.
-  Code woven in by Terry Thorsen 1/2003.
-
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
-
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
-  (the contents of which are also included in zip.h) for terms of use.
-  If, for some reason, all these files are missing, the Info-ZIP license
-  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
-
-        crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
-
-  The encryption/decryption parts of this source code (as opposed to the
-  non-echoing password parts) were originally written in Europe.  The
-  whole source package can be freely distributed, including from the USA.
-  (Prior to January 2000, re-export from the US was a violation of US law.)
-
-        This encryption code is a direct transcription of the algorithm from
-  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
-  file (appnote.txt) is distributed with the PKZIP program (even in the
-  version without encryption capabilities).
-
-        ------------------------------------------------------------------------------------
-
-        Changes in unzip.c
-
-        2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
-  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
-  2007-2008 - Even Rouault - Remove old C style function prototypes
-  2007-2008 - Even Rouault - Add unzip support for ZIP64
-
-        Copyright (C) 2007-2008 Even Rouault
-
-
-        Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
-  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
-                                should only read the compressed/uncompressed size from the Zip64 format if
-                                the size from normal header was 0xFFFFFFFF
-  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
-        Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
-                                Patch created by Daniel Borca
-
-  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
-
-  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
-
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef NOUNCRYPT
-        #define NOUNCRYPT
-#endif
-
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-#  include <stddef.h>
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-    extern int errno;
-#else
-#   include <errno.h>
-#endif
-
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-#    define CASESENSITIVITYDEFAULT_NO
-#  endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-const char unz_copyright[] =
-   " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info64_internal_s
-{
-    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
-} unz_file_info64_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
-    when reading and decompress it */
-typedef struct
-{
-    char  *read_buffer;         /* internal buffer for compressed data */
-    z_stream stream;            /* zLib stream structure for inflate */
-
-#ifdef HAVE_BZIP2
-    bz_stream bstream;          /* bzLib stream structure for bziped */
-#endif
-
-    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
-    uLong stream_initialised;   /* flag set if stream structure is initialised*/
-
-    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
-    uInt  size_local_extrafield;/* size of the local extra field */
-    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
-    ZPOS64_T total_out_64;
-
-    uLong crc32;                /* crc32 of all data uncompressed */
-    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
-    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
-    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
-    zlib_filefunc64_32_def z_filefunc;
-    voidpf filestream;        /* io structore of the zipfile */
-    uLong compression_method;   /* compression method (0==store) */
-    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-    int   raw;
-} file_in_zip64_read_info_s;
-
-
-/* unz64_s contain internal information about the zipfile
-*/
-typedef struct
-{
-    zlib_filefunc64_32_def z_filefunc;
-    int is64bitOpenFunction;
-    voidpf filestream;        /* io structore of the zipfile */
-    unz_global_info64 gi;       /* public global information */
-    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-    ZPOS64_T num_file;             /* number of the current file in the zipfile*/
-    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
-    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
-    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/
-
-    ZPOS64_T size_central_dir;     /* size of the central directory  */
-    ZPOS64_T offset_central_dir;   /* offset of start of central directory with
-                                   respect to the starting disk number */
-
-    unz_file_info64 cur_file_info; /* public info about the current file in zip*/
-    unz_file_info64_internal cur_file_info_internal; /* private info about it*/
-    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
-                                        file if we are decompressing it */
-    int encrypted;
-
-    int isZip64;
-
-#    ifndef NOUNCRYPT
-    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
-    const z_crc_t* pcrc_32_tab;
-#    endif
-} unz64_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
-     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
-   for end of file.
-   IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unz64local_getByte OF((
-    const zlib_filefunc64_32_def* pzlib_filefunc_def,
-    voidpf filestream,
-    int *pi));
-
-local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
-{
-    unsigned char c;
-    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
-    if (err==1)
-    {
-        *pi = (int)c;
-        return UNZ_OK;
-    }
-    else
-    {
-        if (ZERROR64(*pzlib_filefunc_def,filestream))
-            return UNZ_ERRNO;
-        else
-            return UNZ_EOF;
-    }
-}
-
-
-/* ===========================================================================
-   Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unz64local_getShort OF((
-    const zlib_filefunc64_32_def* pzlib_filefunc_def,
-    voidpf filestream,
-    uLong *pX));
-
-local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
-                             voidpf filestream,
-                             uLong *pX)
-{
-    uLong x ;
-    int i = 0;
-    int err;
-
-    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((uLong)i)<<8;
-
-    if (err==UNZ_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int unz64local_getLong OF((
-    const zlib_filefunc64_32_def* pzlib_filefunc_def,
-    voidpf filestream,
-    uLong *pX));
-
-local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
-                            voidpf filestream,
-                            uLong *pX)
-{
-    uLong x ;
-    int i = 0;
-    int err;
-
-    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((uLong)i)<<8;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((uLong)i)<<16;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<24;
-
-    if (err==UNZ_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int unz64local_getLong64 OF((
-    const zlib_filefunc64_32_def* pzlib_filefunc_def,
-    voidpf filestream,
-    ZPOS64_T *pX));
-
-
-local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
-                            voidpf filestream,
-                            ZPOS64_T *pX)
-{
-    ZPOS64_T x ;
-    int i = 0;
-    int err;
-
-    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (ZPOS64_T)i;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<8;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<16;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<24;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<32;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<40;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<48;
-
-    if (err==UNZ_OK)
-        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x |= ((ZPOS64_T)i)<<56;
-
-    if (err==UNZ_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
-{
-    for (;;)
-    {
-        char c1=*(fileName1++);
-        char c2=*(fileName2++);
-        if ((c1>='a') && (c1<='z'))
-            c1 -= 0x20;
-        if ((c2>='a') && (c2<='z'))
-            c2 -= 0x20;
-        if (c1=='\0')
-            return ((c2=='\0') ? 0 : -1);
-        if (c2=='\0')
-            return 1;
-        if (c1<c2)
-            return -1;
-        if (c1>c2)
-            return 1;
-    }
-}
-
-
-#ifdef  CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
-   Compare two filename (fileName1,fileName2).
-   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
-   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
-                                                                or strcasecmp)
-   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
-        (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
-                                                 const char*  fileName2,
-                                                 int iCaseSensitivity)
-
-{
-    if (iCaseSensitivity==0)
-        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
-    if (iCaseSensitivity==1)
-        return strcmp(fileName1,fileName2);
-
-    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
-  Locate the Central directory of a zipfile (at the end, just before
-    the global comment)
-*/
-local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
-    unsigned char* buf;
-    ZPOS64_T uSizeFile;
-    ZPOS64_T uBackRead;
-    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
-    ZPOS64_T uPosFound=0;
-
-    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-        return 0;
-
-
-    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
-
-    if (uMaxBack>uSizeFile)
-        uMaxBack = uSizeFile;
-
-    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-    if (buf==NULL)
-        return 0;
-
-    uBackRead = 4;
-    while (uBackRead<uMaxBack)
-    {
-        uLong uReadSize;
-        ZPOS64_T uReadPos ;
-        int i;
-        if (uBackRead+BUFREADCOMMENT>uMaxBack)
-            uBackRead = uMaxBack;
-        else
-            uBackRead+=BUFREADCOMMENT;
-        uReadPos = uSizeFile-uBackRead ;
-
-        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
-        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            break;
-
-        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-            break;
-
-        for (i=(int)uReadSize-3; (i--)>0;)
-            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
-                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
-            {
-                uPosFound = uReadPos+i;
-                break;
-            }
-
-        if (uPosFound!=0)
-            break;
-    }
-    TRYFREE(buf);
-    return uPosFound;
-}
-
-
-/*
-  Locate the Central directory 64 of a zipfile (at the end, just before
-    the global comment)
-*/
-local ZPOS64_T unz64local_SearchCentralDir64 OF((
-    const zlib_filefunc64_32_def* pzlib_filefunc_def,
-    voidpf filestream));
-
-local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
-                                      voidpf filestream)
-{
-    unsigned char* buf;
-    ZPOS64_T uSizeFile;
-    ZPOS64_T uBackRead;
-    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
-    ZPOS64_T uPosFound=0;
-    uLong uL;
-                ZPOS64_T relativeOffset;
-
-    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-        return 0;
-
-
-    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
-
-    if (uMaxBack>uSizeFile)
-        uMaxBack = uSizeFile;
-
-    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-    if (buf==NULL)
-        return 0;
-
-    uBackRead = 4;
-    while (uBackRead<uMaxBack)
-    {
-        uLong uReadSize;
-        ZPOS64_T uReadPos;
-        int i;
-        if (uBackRead+BUFREADCOMMENT>uMaxBack)
-            uBackRead = uMaxBack;
-        else
-            uBackRead+=BUFREADCOMMENT;
-        uReadPos = uSizeFile-uBackRead ;
-
-        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
-        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            break;
-
-        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-            break;
-
-        for (i=(int)uReadSize-3; (i--)>0;)
-            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
-                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
-            {
-                uPosFound = uReadPos+i;
-                break;
-            }
-
-        if (uPosFound!=0)
-            break;
-    }
-    TRYFREE(buf);
-    if (uPosFound == 0)
-        return 0;
-
-    /* Zip64 end of central directory locator */
-    if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return 0;
-
-    /* the signature, already checked */
-    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
-        return 0;
-
-    /* number of the disk with the start of the zip64 end of  central directory */
-    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
-        return 0;
-    if (uL != 0)
-        return 0;
-
-    /* relative offset of the zip64 end of central directory record */
-    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
-        return 0;
-
-    /* total number of disks */
-    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
-        return 0;
-    if (uL != 1)
-        return 0;
-
-    /* Goto end of central directory record */
-    if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return 0;
-
-     /* the signature */
-    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
-        return 0;
-
-    if (uL != 0x06064b50)
-        return 0;
-
-    return relativeOffset;
-}
-
-/*
-  Open a Zip file. path contain the full pathname (by example,
-     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
-     "zlib/zlib114.zip".
-     If the zipfile cannot be opened (file doesn't exist or in not valid), the
-       return value is NULL.
-     Else, the return value is a unzFile Handle, usable with other function
-       of this unzip package.
-*/
-local unzFile unzOpenInternal (const void *path,
-                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
-                               int is64bitOpenFunction)
-{
-    unz64_s us;
-    unz64_s *s;
-    ZPOS64_T central_pos;
-    uLong   uL;
-
-    uLong number_disk;          /* number of the current dist, used for
-                                   spaning ZIP, unsupported, always 0*/
-    uLong number_disk_with_CD;  /* number the the disk with central dir, used
-                                   for spaning ZIP, unsupported, always 0*/
-    ZPOS64_T number_entry_CD;      /* total number of entries in
-                                   the central dir
-                                   (same than number_entry on nospan) */
-
-    int err=UNZ_OK;
-
-    if (unz_copyright[0]!=' ')
-        return NULL;
-
-    us.z_filefunc.zseek32_file = NULL;
-    us.z_filefunc.ztell32_file = NULL;
-    if (pzlib_filefunc64_32_def==NULL)
-        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
-    else
-        us.z_filefunc = *pzlib_filefunc64_32_def;
-    us.is64bitOpenFunction = is64bitOpenFunction;
-
-
-
-    us.filestream = ZOPEN64(us.z_filefunc,
-                                                 path,
-                                                 ZLIB_FILEFUNC_MODE_READ |
-                                                 ZLIB_FILEFUNC_MODE_EXISTING);
-    if (us.filestream==NULL)
-        return NULL;
-
-    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
-    if (central_pos)
-    {
-        uLong uS;
-        ZPOS64_T uL64;
-
-        us.isZip64 = 1;
-
-        if (ZSEEK64(us.z_filefunc, us.filestream,
-                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        err=UNZ_ERRNO;
-
-        /* the signature, already checked */
-        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* size of zip64 end of central directory record */
-        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* version made by */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* version needed to extract */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* number of this disk */
-        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* number of the disk with the start of the central directory */
-        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* total number of entries in the central directory on this disk */
-        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* total number of entries in the central directory */
-        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        if ((number_entry_CD!=us.gi.number_entry) ||
-            (number_disk_with_CD!=0) ||
-            (number_disk!=0))
-            err=UNZ_BADZIPFILE;
-
-        /* size of the central directory */
-        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* offset of start of central directory with respect to the
-          starting disk number */
-        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        us.gi.size_comment = 0;
-    }
-    else
-    {
-        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
-        if (central_pos==0)
-            err=UNZ_ERRNO;
-
-        us.isZip64 = 0;
-
-        if (ZSEEK64(us.z_filefunc, us.filestream,
-                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err=UNZ_ERRNO;
-
-        /* the signature, already checked */
-        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* number of this disk */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* number of the disk with the start of the central directory */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
-            err=UNZ_ERRNO;
-
-        /* total number of entries in the central dir on this disk */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-            err=UNZ_ERRNO;
-        us.gi.number_entry = uL;
-
-        /* total number of entries in the central dir */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-            err=UNZ_ERRNO;
-        number_entry_CD = uL;
-
-        if ((number_entry_CD!=us.gi.number_entry) ||
-            (number_disk_with_CD!=0) ||
-            (number_disk!=0))
-            err=UNZ_BADZIPFILE;
-
-        /* size of the central directory */
-        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-            err=UNZ_ERRNO;
-        us.size_central_dir = uL;
-
-        /* offset of start of central directory with respect to the
-            starting disk number */
-        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-            err=UNZ_ERRNO;
-        us.offset_central_dir = uL;
-
-        /* zipfile comment length */
-        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
-            err=UNZ_ERRNO;
-    }
-
-    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
-        (err==UNZ_OK))
-        err=UNZ_BADZIPFILE;
-
-    if (err!=UNZ_OK)
-    {
-        ZCLOSE64(us.z_filefunc, us.filestream);
-        return NULL;
-    }
-
-    us.byte_before_the_zipfile = central_pos -
-                            (us.offset_central_dir+us.size_central_dir);
-    us.central_pos = central_pos;
-    us.pfile_in_zip_read = NULL;
-    us.encrypted = 0;
-
-
-    s=(unz64_s*)ALLOC(sizeof(unz64_s));
-    if( s != NULL)
-    {
-        *s=us;
-        unzGoToFirstFile((unzFile)s);
-    }
-    return (unzFile)s;
-}
-
-
-extern unzFile ZEXPORT unzOpen2 (const char *path,
-                                        zlib_filefunc_def* pzlib_filefunc32_def)
-{
-    if (pzlib_filefunc32_def != NULL)
-    {
-        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
-        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
-        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
-    }
-    else
-        return unzOpenInternal(path, NULL, 0);
-}
-
-extern unzFile ZEXPORT unzOpen2_64 (const void *path,
-                                     zlib_filefunc64_def* pzlib_filefunc_def)
-{
-    if (pzlib_filefunc_def != NULL)
-    {
-        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
-        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
-        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
-        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
-        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
-    }
-    else
-        return unzOpenInternal(path, NULL, 1);
-}
-
-extern unzFile ZEXPORT unzOpen (const char *path)
-{
-    return unzOpenInternal(path, NULL, 0);
-}
-
-extern unzFile ZEXPORT unzOpen64 (const void *path)
-{
-    return unzOpenInternal(path, NULL, 1);
-}
-
-/*
-  Close a ZipFile opened with unzOpen.
-  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
-    these files MUST be closed with unzCloseCurrentFile before call unzClose.
-  return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (unzFile file)
-{
-    unz64_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-
-    if (s->pfile_in_zip_read!=NULL)
-        unzCloseCurrentFile(file);
-
-    ZCLOSE64(s->z_filefunc, s->filestream);
-    TRYFREE(s);
-    return UNZ_OK;
-}
-
-
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
-{
-    unz64_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    *pglobal_info=s->gi;
-    return UNZ_OK;
-}
-
-extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
-{
-    unz64_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    /* to do : check if number_entry is not truncated */
-    pglobal_info32->number_entry = (uLong)s->gi.number_entry;
-    pglobal_info32->size_comment = s->gi.size_comment;
-    return UNZ_OK;
-}
-/*
-   Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
-{
-    ZPOS64_T uDate;
-    uDate = (ZPOS64_T)(ulDosDate>>16);
-    ptm->tm_mday = (uInt)(uDate&0x1f) ;
-    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
-    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
-    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
-    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
-    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
-  Get Info about the current file in the zipfile, with internal only info
-*/
-local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
-                                                  unz_file_info64 *pfile_info,
-                                                  unz_file_info64_internal
-                                                  *pfile_info_internal,
-                                                  char *szFileName,
-                                                  uLong fileNameBufferSize,
-                                                  void *extraField,
-                                                  uLong extraFieldBufferSize,
-                                                  char *szComment,
-                                                  uLong commentBufferSize));
-
-local int unz64local_GetCurrentFileInfoInternal (unzFile file,
-                                                  unz_file_info64 *pfile_info,
-                                                  unz_file_info64_internal
-                                                  *pfile_info_internal,
-                                                  char *szFileName,
-                                                  uLong fileNameBufferSize,
-                                                  void *extraField,
-                                                  uLong extraFieldBufferSize,
-                                                  char *szComment,
-                                                  uLong commentBufferSize)
-{
-    unz64_s* s;
-    unz_file_info64 file_info;
-    unz_file_info64_internal file_info_internal;
-    int err=UNZ_OK;
-    uLong uMagic;
-    long lSeek=0;
-    uLong uL;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    if (ZSEEK64(s->z_filefunc, s->filestream,
-              s->pos_in_central_dir+s->byte_before_the_zipfile,
-              ZLIB_FILEFUNC_SEEK_SET)!=0)
-        err=UNZ_ERRNO;
-
-
-    /* we check the magic */
-    if (err==UNZ_OK)
-    {
-        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
-            err=UNZ_ERRNO;
-        else if (uMagic!=0x02014b50)
-            err=UNZ_BADZIPFILE;
-    }
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
-        err=UNZ_ERRNO;
-    file_info.compressed_size = uL;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
-        err=UNZ_ERRNO;
-    file_info.uncompressed_size = uL;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-                // relative offset of local header
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
-        err=UNZ_ERRNO;
-    file_info_internal.offset_curfile = uL;
-
-    lSeek+=file_info.size_filename;
-    if ((err==UNZ_OK) && (szFileName!=NULL))
-    {
-        uLong uSizeRead ;
-        if (file_info.size_filename<fileNameBufferSize)
-        {
-            *(szFileName+file_info.size_filename)='\0';
-            uSizeRead = file_info.size_filename;
-        }
-        else
-            uSizeRead = fileNameBufferSize;
-
-        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
-            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-        lSeek -= uSizeRead;
-    }
-
-    // Read extrafield
-    if ((err==UNZ_OK) && (extraField!=NULL))
-    {
-        ZPOS64_T uSizeRead ;
-        if (file_info.size_file_extra<extraFieldBufferSize)
-            uSizeRead = file_info.size_file_extra;
-        else
-            uSizeRead = extraFieldBufferSize;
-
-        if (lSeek!=0)
-        {
-            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
-                lSeek=0;
-            else
-                err=UNZ_ERRNO;
-        }
-
-        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
-            if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-
-        lSeek += file_info.size_file_extra - (uLong)uSizeRead;
-    }
-    else
-        lSeek += file_info.size_file_extra;
-
-
-    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
-    {
-                                uLong acc = 0;
-
-        // since lSeek now points to after the extra field we need to move back
-        lSeek -= file_info.size_file_extra;
-
-        if (lSeek!=0)
-        {
-            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
-                lSeek=0;
-            else
-                err=UNZ_ERRNO;
-        }
-
-        while(acc < file_info.size_file_extra)
-        {
-            uLong headerId;
-                                                uLong dataSize;
-
-            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
-                err=UNZ_ERRNO;
-
-            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
-                err=UNZ_ERRNO;
-
-            /* ZIP64 extra fields */
-            if (headerId == 0x0001)
-            {
-                                                        uLong uL;
-
-                                                                if(file_info.uncompressed_size == MAXU32)
-                                                                {
-                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
-                                                                                        err=UNZ_ERRNO;
-                                                                }
-
-                                                                if(file_info.compressed_size == MAXU32)
-                                                                {
-                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
-                                                                                  err=UNZ_ERRNO;
-                                                                }
-
-                                                                if(file_info_internal.offset_curfile == MAXU32)
-                                                                {
-                                                                        /* Relative Header offset */
-                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
-                                                                                err=UNZ_ERRNO;
-                                                                }
-
-                                                                if(file_info.disk_num_start == MAXU32)
-                                                                {
-                                                                        /* Disk Start Number */
-                                                                        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
-                                                                                err=UNZ_ERRNO;
-                                                                }
-
-            }
-            else
-            {
-                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
-                    err=UNZ_ERRNO;
-            }
-
-            acc += 2 + 2 + dataSize;
-        }
-    }
-
-    if ((err==UNZ_OK) && (szComment!=NULL))
-    {
-        uLong uSizeRead ;
-        if (file_info.size_file_comment<commentBufferSize)
-        {
-            *(szComment+file_info.size_file_comment)='\0';
-            uSizeRead = file_info.size_file_comment;
-        }
-        else
-            uSizeRead = commentBufferSize;
-
-        if (lSeek!=0)
-        {
-            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
-                lSeek=0;
-            else
-                err=UNZ_ERRNO;
-        }
-
-        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
-            if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-        lSeek+=file_info.size_file_comment - uSizeRead;
-    }
-    else
-        lSeek+=file_info.size_file_comment;
-
-
-    if ((err==UNZ_OK) && (pfile_info!=NULL))
-        *pfile_info=file_info;
-
-    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
-        *pfile_info_internal=file_info_internal;
-
-    return err;
-}
-
-
-
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
-                                          unz_file_info64 * pfile_info,
-                                          char * szFileName, uLong fileNameBufferSize,
-                                          void *extraField, uLong extraFieldBufferSize,
-                                          char* szComment,  uLong commentBufferSize)
-{
-    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
-                                                szFileName,fileNameBufferSize,
-                                                extraField,extraFieldBufferSize,
-                                                szComment,commentBufferSize);
-}
-
-extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
-                                          unz_file_info * pfile_info,
-                                          char * szFileName, uLong fileNameBufferSize,
-                                          void *extraField, uLong extraFieldBufferSize,
-                                          char* szComment,  uLong commentBufferSize)
-{
-    int err;
-    unz_file_info64 file_info64;
-    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
-                                                szFileName,fileNameBufferSize,
-                                                extraField,extraFieldBufferSize,
-                                                szComment,commentBufferSize);
-    if ((err==UNZ_OK) && (pfile_info != NULL))
-    {
-        pfile_info->version = file_info64.version;
-        pfile_info->version_needed = file_info64.version_needed;
-        pfile_info->flag = file_info64.flag;
-        pfile_info->compression_method = file_info64.compression_method;
-        pfile_info->dosDate = file_info64.dosDate;
-        pfile_info->crc = file_info64.crc;
-
-        pfile_info->size_filename = file_info64.size_filename;
-        pfile_info->size_file_extra = file_info64.size_file_extra;
-        pfile_info->size_file_comment = file_info64.size_file_comment;
-
-        pfile_info->disk_num_start = file_info64.disk_num_start;
-        pfile_info->internal_fa = file_info64.internal_fa;
-        pfile_info->external_fa = file_info64.external_fa;
-
-        pfile_info->tmu_date = file_info64.tmu_date,
-
-
-        pfile_info->compressed_size = (uLong)file_info64.compressed_size;
-        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
-
-    }
-    return err;
-}
-/*
-  Set the current file of the zipfile to the first file.
-  return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (unzFile file)
-{
-    int err=UNZ_OK;
-    unz64_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    s->pos_in_central_dir=s->offset_central_dir;
-    s->num_file=0;
-    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
-                                             &s->cur_file_info_internal,
-                                             NULL,0,NULL,0,NULL,0);
-    s->current_file_ok = (err == UNZ_OK);
-    return err;
-}
-
-/*
-  Set the current file of the zipfile to the next file.
-  return UNZ_OK if there is no problem
-  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (unzFile  file)
-{
-    unz64_s* s;
-    int err;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_END_OF_LIST_OF_FILE;
-    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
-      if (s->num_file+1==s->gi.number_entry)
-        return UNZ_END_OF_LIST_OF_FILE;
-
-    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
-            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
-    s->num_file++;
-    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
-                                               &s->cur_file_info_internal,
-                                               NULL,0,NULL,0,NULL,0);
-    s->current_file_ok = (err == UNZ_OK);
-    return err;
-}
-
-
-/*
-  Try locate the file szFileName in the zipfile.
-  For the iCaseSensitivity signification, see unzStringFileNameCompare
-
-  return value :
-  UNZ_OK if the file is found. It becomes the current file.
-  UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
-{
-    unz64_s* s;
-    int err;
-
-    /* We remember the 'current' position in the file so that we can jump
-     * back there if we fail.
-     */
-    unz_file_info64 cur_file_infoSaved;
-    unz_file_info64_internal cur_file_info_internalSaved;
-    ZPOS64_T num_fileSaved;
-    ZPOS64_T pos_in_central_dirSaved;
-
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-
-    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
-        return UNZ_PARAMERROR;
-
-    s=(unz64_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_END_OF_LIST_OF_FILE;
-
-    /* Save the current state */
-    num_fileSaved = s->num_file;
-    pos_in_central_dirSaved = s->pos_in_central_dir;
-    cur_file_infoSaved = s->cur_file_info;
-    cur_file_info_internalSaved = s->cur_file_info_internal;
-
-    err = unzGoToFirstFile(file);
-
-    while (err == UNZ_OK)
-    {
-        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
-        err = unzGetCurrentFileInfo64(file,NULL,
-                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
-                                    NULL,0,NULL,0);
-        if (err == UNZ_OK)
-        {
-            if (unzStringFileNameCompare(szCurrentFileName,
-                                            szFileName,iCaseSensitivity)==0)
-                return UNZ_OK;
-            err = unzGoToNextFile(file);
-        }
-    }
-
-    /* We failed, so restore the state of the 'current file' to where we
-     * were.
-     */
-    s->num_file = num_fileSaved ;
-    s->pos_in_central_dir = pos_in_central_dirSaved ;
-    s->cur_file_info = cur_file_infoSaved;
-    s->cur_file_info_internal = cur_file_info_internalSaved;
-    return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://[email protected])
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
-    ZPOS64_T pos_in_zip_directory;   // offset in file
-    ZPOS64_T num_of_file;            // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
-{
-    unz64_s* s;
-
-    if (file==NULL || file_pos==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_END_OF_LIST_OF_FILE;
-
-    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
-    file_pos->num_of_file           = s->num_file;
-
-    return UNZ_OK;
-}
-
-extern int ZEXPORT unzGetFilePos(
-    unzFile file,
-    unz_file_pos* file_pos)
-{
-    unz64_file_pos file_pos64;
-    int err = unzGetFilePos64(file,&file_pos64);
-    if (err==UNZ_OK)
-    {
-        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
-        file_pos->num_of_file = (uLong)file_pos64.num_of_file;
-    }
-    return err;
-}
-
-extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
-{
-    unz64_s* s;
-    int err;
-
-    if (file==NULL || file_pos==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-
-    /* jump to the right spot */
-    s->pos_in_central_dir = file_pos->pos_in_zip_directory;
-    s->num_file           = file_pos->num_of_file;
-
-    /* set the current file */
-    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
-                                               &s->cur_file_info_internal,
-                                               NULL,0,NULL,0,NULL,0);
-    /* return results */
-    s->current_file_ok = (err == UNZ_OK);
-    return err;
-}
-
-extern int ZEXPORT unzGoToFilePos(
-    unzFile file,
-    unz_file_pos* file_pos)
-{
-    unz64_file_pos file_pos64;
-    if (file_pos == NULL)
-        return UNZ_PARAMERROR;
-
-    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
-    file_pos64.num_of_file = file_pos->num_of_file;
-    return unzGoToFilePos64(file,&file_pos64);
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
-  Read the local header of the current zipfile
-  Check the coherency of the local header and info in the end of central
-        directory about this file
-  store in *piSizeVar the size of extra info in local header
-        (filename and size of extra field data)
-*/
-local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
-                                                    ZPOS64_T * poffset_local_extrafield,
-                                                    uInt  * psize_local_extrafield)
-{
-    uLong uMagic,uData,uFlags;
-    uLong size_filename;
-    uLong size_extra_field;
-    int err=UNZ_OK;
-
-    *piSizeVar = 0;
-    *poffset_local_extrafield = 0;
-    *psize_local_extrafield = 0;
-
-    if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
-                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return UNZ_ERRNO;
-
-
-    if (err==UNZ_OK)
-    {
-        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
-            err=UNZ_ERRNO;
-        else if (uMagic!=0x04034b50)
-            err=UNZ_BADZIPFILE;
-    }
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
-        err=UNZ_ERRNO;
-/*
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
-        err=UNZ_BADZIPFILE;
-*/
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
-        err=UNZ_BADZIPFILE;
-
-    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
-/* #ifdef HAVE_BZIP2 */
-                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
-/* #endif */
-                         (s->cur_file_info.compression_method!=Z_DEFLATED))
-        err=UNZ_BADZIPFILE;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
-        err=UNZ_ERRNO;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
-        err=UNZ_BADZIPFILE;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
-        err=UNZ_ERRNO;
-    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
-        err=UNZ_BADZIPFILE;
-
-    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
-        err=UNZ_ERRNO;
-    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
-        err=UNZ_BADZIPFILE;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
-        err=UNZ_BADZIPFILE;
-
-    *piSizeVar += (uInt)size_filename;
-
-    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
-        err=UNZ_ERRNO;
-    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
-                                    SIZEZIPLOCALHEADER + size_filename;
-    *psize_local_extrafield = (uInt)size_extra_field;
-
-    *piSizeVar += (uInt)size_extra_field;
-
-    return err;
-}
-
-/*
-  Open for reading data the current file in the zipfile.
-  If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
-                                            int* level, int raw, const char* password)
-{
-    int err=UNZ_OK;
-    uInt iSizeVar;
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
-    uInt  size_local_extrafield;    /* size of the local extra field */
-#    ifndef NOUNCRYPT
-    char source[12];
-#    else
-    if (password != NULL)
-        return UNZ_PARAMERROR;
-#    endif
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_PARAMERROR;
-
-    if (s->pfile_in_zip_read != NULL)
-        unzCloseCurrentFile(file);
-
-    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
-        return UNZ_BADZIPFILE;
-
-    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_INTERNALERROR;
-
-    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
-    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
-    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
-    pfile_in_zip_read_info->pos_local_extrafield=0;
-    pfile_in_zip_read_info->raw=raw;
-
-    if (pfile_in_zip_read_info->read_buffer==NULL)
-    {
-        TRYFREE(pfile_in_zip_read_info);
-        return UNZ_INTERNALERROR;
-    }
-
-    pfile_in_zip_read_info->stream_initialised=0;
-
-    if (method!=NULL)
-        *method = (int)s->cur_file_info.compression_method;
-
-    if (level!=NULL)
-    {
-        *level = 6;
-        switch (s->cur_file_info.flag & 0x06)
-        {
-          case 6 : *level = 1; break;
-          case 4 : *level = 2; break;
-          case 2 : *level = 9; break;
-        }
-    }
-
-    if ((s->cur_file_info.compression_method!=0) &&
-/* #ifdef HAVE_BZIP2 */
-        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
-/* #endif */
-        (s->cur_file_info.compression_method!=Z_DEFLATED))
-
-        err=UNZ_BADZIPFILE;
-
-    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
-    pfile_in_zip_read_info->crc32=0;
-    pfile_in_zip_read_info->total_out_64=0;
-    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
-    pfile_in_zip_read_info->filestream=s->filestream;
-    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
-    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
-    pfile_in_zip_read_info->stream.total_out = 0;
-
-    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
-    {
-#ifdef HAVE_BZIP2
-      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
-      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
-      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
-      pfile_in_zip_read_info->bstream.state = (voidpf)0;
-
-      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
-      pfile_in_zip_read_info->stream.zfree = (free_func)0;
-      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
-      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
-      pfile_in_zip_read_info->stream.avail_in = 0;
-
-      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
-      if (err == Z_OK)
-        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
-      else
-      {
-        TRYFREE(pfile_in_zip_read_info);
-        return err;
-      }
-#else
-      pfile_in_zip_read_info->raw=1;
-#endif
-    }
-    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
-    {
-      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
-      pfile_in_zip_read_info->stream.zfree = (free_func)0;
-      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
-      pfile_in_zip_read_info->stream.next_in = 0;
-      pfile_in_zip_read_info->stream.avail_in = 0;
-
-      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
-      if (err == Z_OK)
-        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
-      else
-      {
-        TRYFREE(pfile_in_zip_read_info);
-        return err;
-      }
-        /* windowBits is passed < 0 to tell that there is no zlib header.
-         * Note that in this case inflate *requires* an extra "dummy" byte
-         * after the compressed stream in order to complete decompression and
-         * return Z_STREAM_END.
-         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
-         * size of both compressed and uncompressed data
-         */
-    }
-    pfile_in_zip_read_info->rest_read_compressed =
-            s->cur_file_info.compressed_size ;
-    pfile_in_zip_read_info->rest_read_uncompressed =
-            s->cur_file_info.uncompressed_size ;
-
-
-    pfile_in_zip_read_info->pos_in_zipfile =
-            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
-              iSizeVar;
-
-    pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
-    s->pfile_in_zip_read = pfile_in_zip_read_info;
-                s->encrypted = 0;
-
-#    ifndef NOUNCRYPT
-    if (password != NULL)
-    {
-        int i;
-        s->pcrc_32_tab = get_crc_table();
-        init_keys(password,s->keys,s->pcrc_32_tab);
-        if (ZSEEK64(s->z_filefunc, s->filestream,
-                  s->pfile_in_zip_read->pos_in_zipfile +
-                     s->pfile_in_zip_read->byte_before_the_zipfile,
-                  SEEK_SET)!=0)
-            return UNZ_INTERNALERROR;
-        if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
-            return UNZ_INTERNALERROR;
-
-        for (i = 0; i<12; i++)
-            zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
-        s->pfile_in_zip_read->pos_in_zipfile+=12;
-        s->encrypted=1;
-    }
-#    endif
-
-
-    return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (unzFile file)
-{
-    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
-{
-    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
-{
-    return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/** Addition for GDAL : START */
-
-extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
-{
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    s=(unz64_s*)file;
-    if (file==NULL)
-        return 0; //UNZ_PARAMERROR;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-    if (pfile_in_zip_read_info==NULL)
-        return 0; //UNZ_PARAMERROR;
-    return pfile_in_zip_read_info->pos_in_zipfile +
-                         pfile_in_zip_read_info->byte_before_the_zipfile;
-}
-
-/** Addition for GDAL : END */
-
-/*
-  Read bytes from the current file.
-  buf contain buffer where data must be copied
-  len the size of buf.
-
-  return the number of byte copied if somes bytes are copied
-  return 0 if the end of file was reached
-  return <0 with error code if there is an error
-    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
-{
-    int err=UNZ_OK;
-    uInt iRead = 0;
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-
-    if (pfile_in_zip_read_info->read_buffer == NULL)
-        return UNZ_END_OF_LIST_OF_FILE;
-    if (len==0)
-        return 0;
-
-    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
-    pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
-    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
-        (!(pfile_in_zip_read_info->raw)))
-        pfile_in_zip_read_info->stream.avail_out =
-            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
-    if ((len>pfile_in_zip_read_info->rest_read_compressed+
-           pfile_in_zip_read_info->stream.avail_in) &&
-         (pfile_in_zip_read_info->raw))
-        pfile_in_zip_read_info->stream.avail_out =
-            (uInt)pfile_in_zip_read_info->rest_read_compressed+
-            pfile_in_zip_read_info->stream.avail_in;
-
-    while (pfile_in_zip_read_info->stream.avail_out>0)
-    {
-        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
-            (pfile_in_zip_read_info->rest_read_compressed>0))
-        {
-            uInt uReadThis = UNZ_BUFSIZE;
-            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
-                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
-            if (uReadThis == 0)
-                return UNZ_EOF;
-            if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
-                      pfile_in_zip_read_info->filestream,
-                      pfile_in_zip_read_info->pos_in_zipfile +
-                         pfile_in_zip_read_info->byte_before_the_zipfile,
-                         ZLIB_FILEFUNC_SEEK_SET)!=0)
-                return UNZ_ERRNO;
-            if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
-                      pfile_in_zip_read_info->filestream,
-                      pfile_in_zip_read_info->read_buffer,
-                      uReadThis)!=uReadThis)
-                return UNZ_ERRNO;
-
-
-#            ifndef NOUNCRYPT
-            if(s->encrypted)
-            {
-                uInt i;
-                for(i=0;i<uReadThis;i++)
-                  pfile_in_zip_read_info->read_buffer[i] =
-                      zdecode(s->keys,s->pcrc_32_tab,
-                              pfile_in_zip_read_info->read_buffer[i]);
-            }
-#            endif
-
-
-            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
-            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
-            pfile_in_zip_read_info->stream.next_in =
-                (Bytef*)pfile_in_zip_read_info->read_buffer;
-            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
-        }
-
-        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
-        {
-            uInt uDoCopy,i ;
-
-            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
-                (pfile_in_zip_read_info->rest_read_compressed == 0))
-                return (iRead==0) ? UNZ_EOF : iRead;
-
-            if (pfile_in_zip_read_info->stream.avail_out <
-                            pfile_in_zip_read_info->stream.avail_in)
-                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
-            else
-                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
-            for (i=0;i<uDoCopy;i++)
-                *(pfile_in_zip_read_info->stream.next_out+i) =
-                        *(pfile_in_zip_read_info->stream.next_in+i);
-
-            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
-
-            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
-                                pfile_in_zip_read_info->stream.next_out,
-                                uDoCopy);
-            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
-            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
-            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
-            pfile_in_zip_read_info->stream.next_out += uDoCopy;
-            pfile_in_zip_read_info->stream.next_in += uDoCopy;
-            pfile_in_zip_read_info->stream.total_out += uDoCopy;
-            iRead += uDoCopy;
-        }
-        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
-        {
-#ifdef HAVE_BZIP2
-            uLong uTotalOutBefore,uTotalOutAfter;
-            const Bytef *bufBefore;
-            uLong uOutThis;
-
-            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
-            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
-            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
-            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
-            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
-            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
-            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
-            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
-
-            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
-            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
-
-            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
-
-            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
-            uOutThis = uTotalOutAfter-uTotalOutBefore;
-
-            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
-
-            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
-            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
-            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
-            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
-            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
-            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
-            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
-            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
-            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
-
-            if (err==BZ_STREAM_END)
-              return (iRead==0) ? UNZ_EOF : iRead;
-            if (err!=BZ_OK)
-              break;
-#endif
-        } // end Z_BZIP2ED
-        else
-        {
-            ZPOS64_T uTotalOutBefore,uTotalOutAfter;
-            const Bytef *bufBefore;
-            ZPOS64_T uOutThis;
-            int flush=Z_SYNC_FLUSH;
-
-            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
-            bufBefore = pfile_in_zip_read_info->stream.next_out;
-
-            /*
-            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
-                     pfile_in_zip_read_info->stream.avail_out) &&
-                (pfile_in_zip_read_info->rest_read_compressed == 0))
-                flush = Z_FINISH;
-            */
-            err=inflate(&pfile_in_zip_read_info->stream,flush);
-
-            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
-              err = Z_DATA_ERROR;
-
-            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
-            uOutThis = uTotalOutAfter-uTotalOutBefore;
-
-            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
-
-            pfile_in_zip_read_info->crc32 =
-                crc32(pfile_in_zip_read_info->crc32,bufBefore,
-                        (uInt)(uOutThis));
-
-            pfile_in_zip_read_info->rest_read_uncompressed -=
-                uOutThis;
-
-            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
-            if (err==Z_STREAM_END)
-                return (iRead==0) ? UNZ_EOF : iRead;
-            if (err!=Z_OK)
-                break;
-        }
-    }
-
-    if (err==Z_OK)
-        return iRead;
-    return err;
-}
-
-
-/*
-  Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (unzFile file)
-{
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-    return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
-{
-
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return (ZPOS64_T)-1;
-    s=(unz64_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return (ZPOS64_T)-1;
-
-    return pfile_in_zip_read_info->total_out_64;
-}
-
-
-/*
-  return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (unzFile file)
-{
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
-        return 1;
-    else
-        return 0;
-}
-
-
-
-/*
-Read extra field from the current file (opened by unzOpenCurrentFile)
-This is the local-header version of the extra field (sometimes, there is
-more info in the local-header version than in the central-header)
-
-  if buf==NULL, it return the size of the local extra field that can be read
-
-  if buf!=NULL, len is the size of the buffer, the extra header is copied in
-    buf.
-  the return value is the number of bytes copied in buf, or (if <0)
-    the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
-{
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    uInt read_now;
-    ZPOS64_T size_to_read;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
-                pfile_in_zip_read_info->pos_local_extrafield);
-
-    if (buf==NULL)
-        return (int)size_to_read;
-
-    if (len>size_to_read)
-        read_now = (uInt)size_to_read;
-    else
-        read_now = (uInt)len ;
-
-    if (read_now==0)
-        return 0;
-
-    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
-              pfile_in_zip_read_info->filestream,
-              pfile_in_zip_read_info->offset_local_extrafield +
-              pfile_in_zip_read_info->pos_local_extrafield,
-              ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return UNZ_ERRNO;
-
-    if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
-              pfile_in_zip_read_info->filestream,
-              buf,read_now)!=read_now)
-        return UNZ_ERRNO;
-
-    return (int)read_now;
-}
-
-/*
-  Close the file in zip opened with unzOpenCurrentFile
-  Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (unzFile file)
-{
-    int err=UNZ_OK;
-
-    unz64_s* s;
-    file_in_zip64_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-
-    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
-        (!pfile_in_zip_read_info->raw))
-    {
-        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
-            err=UNZ_CRCERROR;
-    }
-
-
-    TRYFREE(pfile_in_zip_read_info->read_buffer);
-    pfile_in_zip_read_info->read_buffer = NULL;
-    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
-        inflateEnd(&pfile_in_zip_read_info->stream);
-#ifdef HAVE_BZIP2
-    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
-        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
-#endif
-
-
-    pfile_in_zip_read_info->stream_initialised = 0;
-    TRYFREE(pfile_in_zip_read_info);
-
-    s->pfile_in_zip_read=NULL;
-
-    return err;
-}
-
-
-/*
-  Get the global comment string of the ZipFile, in the szComment buffer.
-  uSizeBuf is the size of the szComment buffer.
-  return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
-{
-    unz64_s* s;
-    uLong uReadThis ;
-    if (file==NULL)
-        return (int)UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-
-    uReadThis = uSizeBuf;
-    if (uReadThis>s->gi.size_comment)
-        uReadThis = s->gi.size_comment;
-
-    if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return UNZ_ERRNO;
-
-    if (uReadThis>0)
-    {
-      *szComment='\0';
-      if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
-        return UNZ_ERRNO;
-    }
-
-    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
-        *(szComment+s->gi.size_comment)='\0';
-    return (int)uReadThis;
-}
-
-/* Additions by RX '2004 */
-extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
-{
-    unz64_s* s;
-
-    if (file==NULL)
-          return 0; //UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-    if (!s->current_file_ok)
-      return 0;
-    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
-      if (s->num_file==s->gi.number_entry)
-         return 0;
-    return s->pos_in_central_dir;
-}
-
-extern uLong ZEXPORT unzGetOffset (unzFile file)
-{
-    ZPOS64_T offset64;
-
-    if (file==NULL)
-          return 0; //UNZ_PARAMERROR;
-    offset64 = unzGetOffset64(file);
-    return (uLong)offset64;
-}
-
-extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
-{
-    unz64_s* s;
-    int err;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz64_s*)file;
-
-    s->pos_in_central_dir = pos;
-    s->num_file = s->gi.number_entry;      /* hack */
-    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
-                                              &s->cur_file_info_internal,
-                                              NULL,0,NULL,0,NULL,0);
-    s->current_file_ok = (err == UNZ_OK);
-    return err;
-}
-
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
-{
-    return unzSetOffset64(file,pos);
-}

+ 0 - 437
library/third_party/minizip/unzip.h

@@ -1,437 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications of Unzip for Zip64
-         Copyright (C) 2007-2008 Even Rouault
-
-         Modifications for Zip64 support on both zip and unzip
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         ---------------------------------------------------------------------------------
-
-        Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  ---------------------------------------------------------------------------------
-
-        Changes
-
-        See header of unzip64.c
-
-*/
-
-#ifndef _unz64_H
-#define _unz64_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef  _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#ifdef HAVE_BZIP2
-#include "bzlib.h"
-#endif
-
-#define Z_BZIP2ED 12
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK                          (0)
-#define UNZ_END_OF_LIST_OF_FILE         (-100)
-#define UNZ_ERRNO                       (Z_ERRNO)
-#define UNZ_EOF                         (0)
-#define UNZ_PARAMERROR                  (-102)
-#define UNZ_BADZIPFILE                  (-103)
-#define UNZ_INTERNALERROR               (-104)
-#define UNZ_CRCERROR                    (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
-   These data comes from the end of central dir */
-typedef struct unz_global_info64_s
-{
-    ZPOS64_T number_entry;         /* total number of entries in
-                                     the central dir on this disk */
-    uLong size_comment;         /* size of the global comment of the zipfile */
-} unz_global_info64;
-
-typedef struct unz_global_info_s
-{
-    uLong number_entry;         /* total number of entries in
-                                     the central dir on this disk */
-    uLong size_comment;         /* size of the global comment of the zipfile */
-} unz_global_info;
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info64_s
-{
-    uLong version;              /* version made by                 2 bytes */
-    uLong version_needed;       /* version needed to extract       2 bytes */
-    uLong flag;                 /* general purpose bit flag        2 bytes */
-    uLong compression_method;   /* compression method              2 bytes */
-    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
-    uLong crc;                  /* crc-32                          4 bytes */
-    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */
-    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */
-    uLong size_filename;        /* filename length                 2 bytes */
-    uLong size_file_extra;      /* extra field length              2 bytes */
-    uLong size_file_comment;    /* file comment length             2 bytes */
-
-    uLong disk_num_start;       /* disk number start               2 bytes */
-    uLong internal_fa;          /* internal file attributes        2 bytes */
-    uLong external_fa;          /* external file attributes        4 bytes */
-
-    tm_unz tmu_date;
-} unz_file_info64;
-
-typedef struct unz_file_info_s
-{
-    uLong version;              /* version made by                 2 bytes */
-    uLong version_needed;       /* version needed to extract       2 bytes */
-    uLong flag;                 /* general purpose bit flag        2 bytes */
-    uLong compression_method;   /* compression method              2 bytes */
-    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
-    uLong crc;                  /* crc-32                          4 bytes */
-    uLong compressed_size;      /* compressed size                 4 bytes */
-    uLong uncompressed_size;    /* uncompressed size               4 bytes */
-    uLong size_filename;        /* filename length                 2 bytes */
-    uLong size_file_extra;      /* extra field length              2 bytes */
-    uLong size_file_comment;    /* file comment length             2 bytes */
-
-    uLong disk_num_start;       /* disk number start               2 bytes */
-    uLong internal_fa;          /* internal file attributes        2 bytes */
-    uLong external_fa;          /* external file attributes        4 bytes */
-
-    tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
-                                                 const char* fileName2,
-                                                 int iCaseSensitivity));
-/*
-   Compare two filename (fileName1,fileName2).
-   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
-   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
-                                or strcasecmp)
-   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
-    (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-extern unzFile ZEXPORT unzOpen64 OF((const void *path));
-/*
-  Open a Zip file. path contain the full pathname (by example,
-     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
-     "zlib/zlib113.zip".
-     If the zipfile cannot be opened (file don't exist or in not valid), the
-       return value is NULL.
-     Else, the return value is a unzFile Handle, usable with other function
-       of this unzip package.
-     the "64" function take a const void* pointer, because the path is just the
-       value passed to the open64_file_func callback.
-     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
-       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
-       does not describe the reality
-*/
-
-
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
-                                    zlib_filefunc_def* pzlib_filefunc_def));
-/*
-   Open a Zip file, like unzOpen, but provide a set of file low level API
-      for read/write the zip file (see ioapi.h)
-*/
-
-extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
-                                    zlib_filefunc64_def* pzlib_filefunc_def));
-/*
-   Open a Zip file, like unz64Open, but provide a set of file low level API
-      for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
-  Close a ZipFile opened with unzOpen.
-  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
-    these files MUST be closed with unzCloseCurrentFile before call unzClose.
-  return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
-                                        unz_global_info *pglobal_info));
-
-extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
-                                        unz_global_info64 *pglobal_info));
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
-                                           char *szComment,
-                                           uLong uSizeBuf));
-/*
-  Get the global comment string of the ZipFile, in the szComment buffer.
-  uSizeBuf is the size of the szComment buffer.
-  return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
-  Set the current file of the zipfile to the first file.
-  return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
-  Set the current file of the zipfile to the next file.
-  return UNZ_OK if there is no problem
-  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
-                     const char *szFileName,
-                     int iCaseSensitivity));
-/*
-  Try locate the file szFileName in the zipfile.
-  For the iCaseSensitivity signification, see unzStringFileNameCompare
-
-  return value :
-  UNZ_OK if the file is found. It becomes the current file.
-  UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
-    uLong pos_in_zip_directory;   /* offset in zip file directory */
-    uLong num_of_file;            /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
-    unzFile file,
-    unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
-    unzFile file,
-    unz_file_pos* file_pos);
-
-typedef struct unz64_file_pos_s
-{
-    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */
-    ZPOS64_T num_of_file;            /* # of file */
-} unz64_file_pos;
-
-extern int ZEXPORT unzGetFilePos64(
-    unzFile file,
-    unz64_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos64(
-    unzFile file,
-    const unz64_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
-                         unz_file_info64 *pfile_info,
-                         char *szFileName,
-                         uLong fileNameBufferSize,
-                         void *extraField,
-                         uLong extraFieldBufferSize,
-                         char *szComment,
-                         uLong commentBufferSize));
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
-                         unz_file_info *pfile_info,
-                         char *szFileName,
-                         uLong fileNameBufferSize,
-                         void *extraField,
-                         uLong extraFieldBufferSize,
-                         char *szComment,
-                         uLong commentBufferSize));
-/*
-  Get Info about the current file
-  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
-        the current file
-  if szFileName!=NULL, the filemane string will be copied in szFileName
-            (fileNameBufferSize is the size of the buffer)
-  if extraField!=NULL, the extra field information will be copied in extraField
-            (extraFieldBufferSize is the size of the buffer).
-            This is the Central-header version of the extra field
-  if szComment!=NULL, the comment string of the file will be copied in szComment
-            (commentBufferSize is the size of the buffer)
-*/
-
-
-/** Addition for GDAL : START */
-
-extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
-
-/** Addition for GDAL : END */
-
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
-   from it, and close it (you can close it before reading all the file)
-   */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
-  Open for reading data the current file in the zipfile.
-  If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
-                                                  const char* password));
-/*
-  Open for reading data the current file in the zipfile.
-  password is a crypting password
-  If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
-                                           int* method,
-                                           int* level,
-                                           int raw));
-/*
-  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
-    if raw==1
-  *method will receive method of compression, *level will receive level of
-     compression
-  note : you can set level parameter as NULL (if you did not want known level,
-         but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
-                                           int* method,
-                                           int* level,
-                                           int raw,
-                                           const char* password));
-/*
-  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
-    if raw==1
-  *method will receive method of compression, *level will receive level of
-     compression
-  note : you can set level parameter as NULL (if you did not want known level,
-         but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
-  Close the file in zip opened with unzOpenCurrentFile
-  Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
-                      voidp buf,
-                      unsigned len));
-/*
-  Read bytes from the current file (opened by unzOpenCurrentFile)
-  buf contain buffer where data must be copied
-  len the size of buf.
-
-  return the number of byte copied if somes bytes are copied
-  return 0 if the end of file was reached
-  return <0 with error code if there is an error
-    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-
-extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
-/*
-  Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
-  return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
-                                             voidp buf,
-                                             unsigned len));
-/*
-  Read extra field from the current file (opened by unzOpenCurrentFile)
-  This is the local-header version of the extra field (sometimes, there is
-    more info in the local-header version than in the central-header)
-
-  if buf==NULL, it return the size of the local extra field
-
-  if buf!=NULL, len is the size of the buffer, the extra header is copied in
-    buf.
-  the return value is the number of bytes copied in buf, or (if <0)
-    the error code
-*/
-
-/***************************************************************************/
-
-/* Get the current file offset */
-extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
-extern uLong ZEXPORT unzGetOffset (unzFile file);
-
-/* Set the current file offset */
-extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz64_H */

+ 0 - 2007
library/third_party/minizip/zip.c

@@ -1,2007 +0,0 @@
-/* zip.c -- IO on .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         Changes
-   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
-   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
-   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
-   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
-                                 It is used when recreting zip archive with RAW when deleting items from a zip.
-                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
-   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
-   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
-
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "zlib.h"
-#include "zip.h"
-
-#ifdef STDC
-#  include <stddef.h>
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-    extern int errno;
-#else
-#   include <errno.h>
-#endif
-
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY   (0x0) /* platform depedent */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (64*1024) //(16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-
-// NOT sure that this work on ALL platform
-#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
-
-#ifndef SEEK_CUR
-#define SEEK_CUR    1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END    2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET    0
-#endif
-
-#ifndef DEF_MEM_LEVEL
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-#endif
-const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC    (0x04034b50)
-#define CENTRALHEADERMAGIC  (0x02014b50)
-#define ENDHEADERMAGIC      (0x06054b50)
-#define ZIP64ENDHEADERMAGIC      (0x6064b50)
-#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET  (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
-  struct linkedlist_datablock_internal_s* next_datablock;
-  uLong  avail_in_this_block;
-  uLong  filled_in_this_block;
-  uLong  unused; /* for future use and alignement */
-  unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
-    linkedlist_datablock_internal* first_block;
-    linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
-    z_stream stream;            /* zLib stream structure for inflate */
-#ifdef HAVE_BZIP2
-    bz_stream bstream;          /* bzLib stream structure for bziped */
-#endif
-
-    int  stream_initialised;    /* 1 is stream is initialised */
-    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
-
-    ZPOS64_T pos_local_header;     /* offset of the local header of the file
-                                     currenty writing */
-    char* central_header;       /* central header data for the current file */
-    uLong size_centralExtra;
-    uLong size_centralheader;   /* size of the central header for cur file */
-    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
-    uLong flag;                 /* flag of the file currently writing */
-
-    int  method;                /* compression method of file currenty wr.*/
-    int  raw;                   /* 1 for directly writing raw data */
-    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
-    uLong dosDate;
-    uLong crc32;
-    int  encrypt;
-    int  zip64;               /* Add ZIP64 extened information in the extra field */
-    ZPOS64_T pos_zip64extrainfo;
-    ZPOS64_T totalCompressedData;
-    ZPOS64_T totalUncompressedData;
-#ifndef NOCRYPT
-    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
-    const z_crc_t* pcrc_32_tab;
-    int crypt_header_size;
-#endif
-} curfile64_info;
-
-typedef struct
-{
-    zlib_filefunc64_32_def z_filefunc;
-    voidpf filestream;        /* io structore of the zipfile */
-    linkedlist_data central_dir;/* datablock with central dir in construction*/
-    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
-    curfile64_info ci;            /* info on the file curretly writing */
-
-    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
-    ZPOS64_T add_position_when_writting_offset;
-    ZPOS64_T number_entry;
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-    char *globalcomment;
-#endif
-
-} zip64_internal;
-
-
-#ifndef NOCRYPT
-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-#include "crypt.h"
-#endif
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
-    linkedlist_datablock_internal* ldi;
-    ldi = (linkedlist_datablock_internal*)
-                 ALLOC(sizeof(linkedlist_datablock_internal));
-    if (ldi!=NULL)
-    {
-        ldi->next_datablock = NULL ;
-        ldi->filled_in_this_block = 0 ;
-        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
-    }
-    return ldi;
-}
-
-local void free_datablock(linkedlist_datablock_internal* ldi)
-{
-    while (ldi!=NULL)
-    {
-        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
-        TRYFREE(ldi);
-        ldi = ldinext;
-    }
-}
-
-local void init_linkedlist(linkedlist_data* ll)
-{
-    ll->first_block = ll->last_block = NULL;
-}
-
-local void free_linkedlist(linkedlist_data* ll)
-{
-    free_datablock(ll->first_block);
-    ll->first_block = ll->last_block = NULL;
-}
-
-
-local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
-{
-    linkedlist_datablock_internal* ldi;
-    const unsigned char* from_copy;
-
-    if (ll==NULL)
-        return ZIP_INTERNALERROR;
-
-    if (ll->last_block == NULL)
-    {
-        ll->first_block = ll->last_block = allocate_new_datablock();
-        if (ll->first_block == NULL)
-            return ZIP_INTERNALERROR;
-    }
-
-    ldi = ll->last_block;
-    from_copy = (unsigned char*)buf;
-
-    while (len>0)
-    {
-        uInt copy_this;
-        uInt i;
-        unsigned char* to_copy;
-
-        if (ldi->avail_in_this_block==0)
-        {
-            ldi->next_datablock = allocate_new_datablock();
-            if (ldi->next_datablock == NULL)
-                return ZIP_INTERNALERROR;
-            ldi = ldi->next_datablock ;
-            ll->last_block = ldi;
-        }
-
-        if (ldi->avail_in_this_block < len)
-            copy_this = (uInt)ldi->avail_in_this_block;
-        else
-            copy_this = (uInt)len;
-
-        to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
-        for (i=0;i<copy_this;i++)
-            *(to_copy+i)=*(from_copy+i);
-
-        ldi->filled_in_this_block += copy_this;
-        ldi->avail_in_this_block -= copy_this;
-        from_copy += copy_this ;
-        len -= copy_this;
-    }
-    return ZIP_OK;
-}
-
-
-
-/****************************************************************************/
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-/* ===========================================================================
-   Inputs a long in LSB order to the given file
-   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
-*/
-
-local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
-local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
-{
-    unsigned char buf[8];
-    int n;
-    for (n = 0; n < nbByte; n++)
-    {
-        buf[n] = (unsigned char)(x & 0xff);
-        x >>= 8;
-    }
-    if (x != 0)
-      {     /* data overflow - hack for ZIP64 (X Roche) */
-      for (n = 0; n < nbByte; n++)
-        {
-          buf[n] = 0xff;
-        }
-      }
-
-    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
-        return ZIP_ERRNO;
-    else
-        return ZIP_OK;
-}
-
-local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
-local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
-{
-    unsigned char* buf=(unsigned char*)dest;
-    int n;
-    for (n = 0; n < nbByte; n++) {
-        buf[n] = (unsigned char)(x & 0xff);
-        x >>= 8;
-    }
-
-    if (x != 0)
-    {     /* data overflow - hack for ZIP64 */
-       for (n = 0; n < nbByte; n++)
-       {
-          buf[n] = 0xff;
-       }
-    }
-}
-
-/****************************************************************************/
-
-
-local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
-{
-    uLong year = (uLong)ptm->tm_year;
-    if (year>=1980)
-        year-=1980;
-    else if (year>=80)
-        year-=80;
-    return
-      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
-        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
-
-local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
-{
-    unsigned char c;
-    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
-    if (err==1)
-    {
-        *pi = (int)c;
-        return ZIP_OK;
-    }
-    else
-    {
-        if (ZERROR64(*pzlib_filefunc_def,filestream))
-            return ZIP_ERRNO;
-        else
-            return ZIP_EOF;
-    }
-}
-
-
-/* ===========================================================================
-   Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
-
-local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
-{
-    uLong x ;
-    int i = 0;
-    int err;
-
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==ZIP_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
-
-local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
-{
-    uLong x ;
-    int i = 0;
-    int err;
-
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<16;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<24;
-
-    if (err==ZIP_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
-
-
-local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
-{
-  ZPOS64_T x;
-  int i = 0;
-  int err;
-
-  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x = (ZPOS64_T)i;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<8;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<16;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<24;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<32;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<40;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<48;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<56;
-
-  if (err==ZIP_OK)
-    *pX = x;
-  else
-    *pX = 0;
-
-  return err;
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-/*
-  Locate the Central directory of a zipfile (at the end, just before
-    the global comment)
-*/
-local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-
-local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
-  unsigned char* buf;
-  ZPOS64_T uSizeFile;
-  ZPOS64_T uBackRead;
-  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
-  ZPOS64_T uPosFound=0;
-
-  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-    return 0;
-
-
-  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
-
-  if (uMaxBack>uSizeFile)
-    uMaxBack = uSizeFile;
-
-  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-  if (buf==NULL)
-    return 0;
-
-  uBackRead = 4;
-  while (uBackRead<uMaxBack)
-  {
-    uLong uReadSize;
-    ZPOS64_T uReadPos ;
-    int i;
-    if (uBackRead+BUFREADCOMMENT>uMaxBack)
-      uBackRead = uMaxBack;
-    else
-      uBackRead+=BUFREADCOMMENT;
-    uReadPos = uSizeFile-uBackRead ;
-
-    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
-    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-      break;
-
-    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-      break;
-
-    for (i=(int)uReadSize-3; (i--)>0;)
-      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
-        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
-      {
-        uPosFound = uReadPos+i;
-        break;
-      }
-
-      if (uPosFound!=0)
-        break;
-  }
-  TRYFREE(buf);
-  return uPosFound;
-}
-
-/*
-Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
-the global comment)
-*/
-local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-
-local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
-  unsigned char* buf;
-  ZPOS64_T uSizeFile;
-  ZPOS64_T uBackRead;
-  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
-  ZPOS64_T uPosFound=0;
-  uLong uL;
-  ZPOS64_T relativeOffset;
-
-  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-    return 0;
-
-  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
-
-  if (uMaxBack>uSizeFile)
-    uMaxBack = uSizeFile;
-
-  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-  if (buf==NULL)
-    return 0;
-
-  uBackRead = 4;
-  while (uBackRead<uMaxBack)
-  {
-    uLong uReadSize;
-    ZPOS64_T uReadPos;
-    int i;
-    if (uBackRead+BUFREADCOMMENT>uMaxBack)
-      uBackRead = uMaxBack;
-    else
-      uBackRead+=BUFREADCOMMENT;
-    uReadPos = uSizeFile-uBackRead ;
-
-    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
-    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-      break;
-
-    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-      break;
-
-    for (i=(int)uReadSize-3; (i--)>0;)
-    {
-      // Signature "0x07064b50" Zip64 end of central directory locater
-      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
-      {
-        uPosFound = uReadPos+i;
-        break;
-      }
-    }
-
-      if (uPosFound!=0)
-        break;
-  }
-
-  TRYFREE(buf);
-  if (uPosFound == 0)
-    return 0;
-
-  /* Zip64 end of central directory locator */
-  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
-    return 0;
-
-  /* the signature, already checked */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-
-  /* number of the disk with the start of the zip64 end of  central directory */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-  if (uL != 0)
-    return 0;
-
-  /* relative offset of the zip64 end of central directory record */
-  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
-    return 0;
-
-  /* total number of disks */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-  if (uL != 1)
-    return 0;
-
-  /* Goto Zip64 end of central directory record */
-  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
-    return 0;
-
-  /* the signature */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-
-  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
-    return 0;
-
-  return relativeOffset;
-}
-
-int LoadCentralDirectoryRecord(zip64_internal* pziinit)
-{
-  int err=ZIP_OK;
-  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-
-  ZPOS64_T size_central_dir;     /* size of the central directory  */
-  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
-  ZPOS64_T central_pos;
-  uLong uL;
-
-  uLong number_disk;          /* number of the current dist, used for
-                              spaning ZIP, unsupported, always 0*/
-  uLong number_disk_with_CD;  /* number the the disk with central dir, used
-                              for spaning ZIP, unsupported, always 0*/
-  ZPOS64_T number_entry;
-  ZPOS64_T number_entry_CD;      /* total number of entries in
-                                the central dir
-                                (same than number_entry on nospan) */
-  uLong VersionMadeBy;
-  uLong VersionNeeded;
-  uLong size_comment;
-
-  int hasZIP64Record = 0;
-
-  // check first if we find a ZIP64 record
-  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
-  if(central_pos > 0)
-  {
-    hasZIP64Record = 1;
-  }
-  else if(central_pos == 0)
-  {
-    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
-  }
-
-/* disable to allow appending to empty ZIP archive
-        if (central_pos==0)
-            err=ZIP_ERRNO;
-*/
-
-  if(hasZIP64Record)
-  {
-    ZPOS64_T sizeEndOfCentralDirectory;
-    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
-      err=ZIP_ERRNO;
-
-    /* the signature, already checked */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* size of zip64 end of central directory record */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* version made by */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* version needed to extract */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of this disk */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of the disk with the start of the central directory */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* total number of entries in the central directory on this disk */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* total number of entries in the central directory */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
-      err=ZIP_BADZIPFILE;
-
-    /* size of the central directory */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* offset of start of central directory with respect to the
-    starting disk number */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    // TODO..
-    // read the comment from the standard central header.
-    size_comment = 0;
-  }
-  else
-  {
-    // Read End of central Directory info
-    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-      err=ZIP_ERRNO;
-
-    /* the signature, already checked */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of this disk */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of the disk with the start of the central directory */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* total number of entries in the central dir on this disk */
-    number_entry = 0;
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      number_entry = uL;
-
-    /* total number of entries in the central dir */
-    number_entry_CD = 0;
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      number_entry_CD = uL;
-
-    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
-      err=ZIP_BADZIPFILE;
-
-    /* size of the central directory */
-    size_central_dir = 0;
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      size_central_dir = uL;
-
-    /* offset of start of central directory with respect to the starting disk number */
-    offset_central_dir = 0;
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      offset_central_dir = uL;
-
-
-    /* zipfile global comment length */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
-      err=ZIP_ERRNO;
-  }
-
-  if ((central_pos<offset_central_dir+size_central_dir) &&
-    (err==ZIP_OK))
-    err=ZIP_BADZIPFILE;
-
-  if (err!=ZIP_OK)
-  {
-    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
-    return ZIP_ERRNO;
-  }
-
-  if (size_comment>0)
-  {
-    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
-    if (pziinit->globalcomment)
-    {
-      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
-      pziinit->globalcomment[size_comment]=0;
-    }
-  }
-
-  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
-  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
-
-  {
-    ZPOS64_T size_central_dir_to_read = size_central_dir;
-    size_t buf_size = SIZEDATA_INDATABLOCK;
-    void* buf_read = (void*)ALLOC(buf_size);
-    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
-      err=ZIP_ERRNO;
-
-    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
-    {
-      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
-      if (read_this > size_central_dir_to_read)
-        read_this = size_central_dir_to_read;
-
-      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
-        err=ZIP_ERRNO;
-
-      if (err==ZIP_OK)
-        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
-
-      size_central_dir_to_read-=read_this;
-    }
-    TRYFREE(buf_read);
-  }
-  pziinit->begin_pos = byte_before_the_zipfile;
-  pziinit->number_entry = number_entry_CD;
-
-  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
-    err=ZIP_ERRNO;
-
-  return err;
-}
-
-
-#endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-
-/************************************************************/
-extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
-{
-    zip64_internal ziinit;
-    zip64_internal* zi;
-    int err=ZIP_OK;
-
-    ziinit.z_filefunc.zseek32_file = NULL;
-    ziinit.z_filefunc.ztell32_file = NULL;
-    if (pzlib_filefunc64_32_def==NULL)
-        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
-    else
-        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
-
-    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
-                  pathname,
-                  (append == APPEND_STATUS_CREATE) ?
-                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
-                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
-
-    if (ziinit.filestream == NULL)
-        return NULL;
-
-    if (append == APPEND_STATUS_CREATEAFTER)
-        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
-
-    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
-    ziinit.in_opened_file_inzip = 0;
-    ziinit.ci.stream_initialised = 0;
-    ziinit.number_entry = 0;
-    ziinit.add_position_when_writting_offset = 0;
-    init_linkedlist(&(ziinit.central_dir));
-
-
-
-    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
-    if (zi==NULL)
-    {
-        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
-        return NULL;
-    }
-
-    /* now we add file in a zipfile */
-#    ifndef NO_ADDFILEINEXISTINGZIP
-    ziinit.globalcomment = NULL;
-    if (append == APPEND_STATUS_ADDINZIP)
-    {
-      // Read and Cache Central Directory Records
-      err = LoadCentralDirectoryRecord(&ziinit);
-    }
-
-    if (globalcomment)
-    {
-      *globalcomment = ziinit.globalcomment;
-    }
-#    endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-    if (err != ZIP_OK)
-    {
-#    ifndef NO_ADDFILEINEXISTINGZIP
-        TRYFREE(ziinit.globalcomment);
-#    endif /* !NO_ADDFILEINEXISTINGZIP*/
-        TRYFREE(zi);
-        return NULL;
-    }
-    else
-    {
-        *zi = ziinit;
-        return (zipFile)zi;
-    }
-}
-
-extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
-{
-    if (pzlib_filefunc32_def != NULL)
-    {
-        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
-        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
-        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
-    }
-    else
-        return zipOpen3(pathname, append, globalcomment, NULL);
-}
-
-extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
-{
-    if (pzlib_filefunc_def != NULL)
-    {
-        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
-        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
-        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
-        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
-        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
-    }
-    else
-        return zipOpen3(pathname, append, globalcomment, NULL);
-}
-
-
-
-extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
-{
-    return zipOpen3((const void*)pathname,append,NULL,NULL);
-}
-
-extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
-{
-    return zipOpen3(pathname,append,NULL,NULL);
-}
-
-int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
-{
-  /* write the local header */
-  int err;
-  uInt size_filename = (uInt)strlen(filename);
-  uInt size_extrafield = size_extrafield_local;
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
-
-  if (err==ZIP_OK)
-  {
-    if(zi->ci.zip64)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
-  }
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
-
-  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
-  if (err==ZIP_OK)
-  {
-    if(zi->ci.zip64)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
-  }
-  if (err==ZIP_OK)
-  {
-    if(zi->ci.zip64)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
-  }
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
-
-  if(zi->ci.zip64)
-  {
-    size_extrafield += 20;
-  }
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
-
-  if ((err==ZIP_OK) && (size_filename > 0))
-  {
-    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
-      err = ZIP_ERRNO;
-  }
-
-  if ((err==ZIP_OK) && (size_extrafield_local > 0))
-  {
-    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
-      err = ZIP_ERRNO;
-  }
-
-
-  if ((err==ZIP_OK) && (zi->ci.zip64))
-  {
-      // write the Zip64 extended info
-      short HeaderID = 1;
-      short DataSize = 16;
-      ZPOS64_T CompressedSize = 0;
-      ZPOS64_T UncompressedSize = 0;
-
-      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
-      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
-
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
-
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
-  }
-
-  return err;
-}
-
-/*
- NOTE.
- When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
- before calling this function it can be done with zipRemoveExtraInfoBlock
-
- It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
- unnecessary allocations.
- */
-extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting,
-                                         uLong versionMadeBy, uLong flagBase, int zip64)
-{
-    zip64_internal* zi;
-    uInt size_filename;
-    uInt size_comment;
-    uInt i;
-    int err = ZIP_OK;
-
-#    ifdef NOCRYPT
-    (void)(crcForCrypting);
-    if (password != NULL)
-        return ZIP_PARAMERROR;
-#    endif
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-
-#ifdef HAVE_BZIP2
-    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
-      return ZIP_PARAMERROR;
-#else
-    if ((method!=0) && (method!=Z_DEFLATED))
-      return ZIP_PARAMERROR;
-#endif
-
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 1)
-    {
-        err = zipCloseFileInZip (file);
-        if (err != ZIP_OK)
-            return err;
-    }
-
-    if (filename==NULL)
-        filename="-";
-
-    if (comment==NULL)
-        size_comment = 0;
-    else
-        size_comment = (uInt)strlen(comment);
-
-    size_filename = (uInt)strlen(filename);
-
-    if (zipfi == NULL)
-        zi->ci.dosDate = 0;
-    else
-    {
-        if (zipfi->dosDate != 0)
-            zi->ci.dosDate = zipfi->dosDate;
-        else
-          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
-    }
-
-    zi->ci.flag = flagBase;
-    if ((level==8) || (level==9))
-      zi->ci.flag |= 2;
-    if (level==2)
-      zi->ci.flag |= 4;
-    if (level==1)
-      zi->ci.flag |= 6;
-    if (password != NULL)
-      zi->ci.flag |= 1;
-
-    zi->ci.crc32 = 0;
-    zi->ci.method = method;
-    zi->ci.encrypt = 0;
-    zi->ci.stream_initialised = 0;
-    zi->ci.pos_in_buffered_data = 0;
-    zi->ci.raw = raw;
-    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
-
-    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
-    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
-
-    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
-
-    zi->ci.size_centralExtra = size_extrafield_global;
-    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
-    /* version info */
-    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
-    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
-    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
-    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
-    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
-    if (zipfi==NULL)
-        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
-    else
-        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
-    if (zipfi==NULL)
-        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
-    else
-        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
-    if(zi->ci.pos_local_header >= 0xffffffff)
-      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
-    else
-      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
-
-    for (i=0;i<size_filename;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
-    for (i=0;i<size_extrafield_global;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
-              *(((const char*)extrafield_global)+i);
-
-    for (i=0;i<size_comment;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
-              size_extrafield_global+i) = *(comment+i);
-    if (zi->ci.central_header == NULL)
-        return ZIP_INTERNALERROR;
-
-    zi->ci.zip64 = zip64;
-    zi->ci.totalCompressedData = 0;
-    zi->ci.totalUncompressedData = 0;
-    zi->ci.pos_zip64extrainfo = 0;
-
-    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
-
-#ifdef HAVE_BZIP2
-    zi->ci.bstream.avail_in = (uInt)0;
-    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
-    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
-    zi->ci.bstream.total_in_hi32 = 0;
-    zi->ci.bstream.total_in_lo32 = 0;
-    zi->ci.bstream.total_out_hi32 = 0;
-    zi->ci.bstream.total_out_lo32 = 0;
-#endif
-
-    zi->ci.stream.avail_in = (uInt)0;
-    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-    zi->ci.stream.next_out = zi->ci.buffered_data;
-    zi->ci.stream.total_in = 0;
-    zi->ci.stream.total_out = 0;
-    zi->ci.stream.data_type = Z_BINARY;
-
-#ifdef HAVE_BZIP2
-    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-#else
-    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-#endif
-    {
-        if(zi->ci.method == Z_DEFLATED)
-        {
-          zi->ci.stream.zalloc = (alloc_func)0;
-          zi->ci.stream.zfree = (free_func)0;
-          zi->ci.stream.opaque = (voidpf)0;
-
-          if (windowBits>0)
-              windowBits = -windowBits;
-
-          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
-
-          if (err==Z_OK)
-              zi->ci.stream_initialised = Z_DEFLATED;
-        }
-        else if(zi->ci.method == Z_BZIP2ED)
-        {
-#ifdef HAVE_BZIP2
-            // Init BZip stuff here
-          zi->ci.bstream.bzalloc = 0;
-          zi->ci.bstream.bzfree = 0;
-          zi->ci.bstream.opaque = (voidpf)0;
-
-          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
-          if(err == BZ_OK)
-            zi->ci.stream_initialised = Z_BZIP2ED;
-#endif
-        }
-
-    }
-
-#    ifndef NOCRYPT
-    zi->ci.crypt_header_size = 0;
-    if ((err==Z_OK) && (password != NULL))
-    {
-        unsigned char bufHead[RAND_HEAD_LEN];
-        unsigned int sizeHead;
-        zi->ci.encrypt = 1;
-        zi->ci.pcrc_32_tab = get_crc_table();
-        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
-
-        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
-        zi->ci.crypt_header_size = sizeHead;
-
-        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
-                err = ZIP_ERRNO;
-    }
-#    endif
-
-    if (err==Z_OK)
-        zi->in_opened_file_inzip = 1;
-    return err;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting,
-                                         uLong versionMadeBy, uLong flagBase)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 windowBits, memLevel, strategy,
-                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 windowBits, memLevel, strategy,
-                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting, int zip64)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 windowBits, memLevel, strategy,
-                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void* extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level, int raw)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void* extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level, int raw, int zip64)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, zip64);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void*extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level, int zip64)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, 0,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, zip64);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void*extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, 0,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, 0);
-}
-
-local int zip64FlushWriteBuffer(zip64_internal* zi)
-{
-    int err=ZIP_OK;
-
-    if (zi->ci.encrypt != 0)
-    {
-#ifndef NOCRYPT
-        uInt i;
-        int t;
-        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
-            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
-#endif
-    }
-
-    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
-      err = ZIP_ERRNO;
-
-    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
-
-#ifdef HAVE_BZIP2
-    if(zi->ci.method == Z_BZIP2ED)
-    {
-      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
-      zi->ci.bstream.total_in_lo32 = 0;
-      zi->ci.bstream.total_in_hi32 = 0;
-    }
-    else
-#endif
-    {
-      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
-      zi->ci.stream.total_in = 0;
-    }
-
-
-    zi->ci.pos_in_buffered_data = 0;
-
-    return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
-{
-    zip64_internal* zi;
-    int err=ZIP_OK;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 0)
-        return ZIP_PARAMERROR;
-
-    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
-
-#ifdef HAVE_BZIP2
-    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
-    {
-      zi->ci.bstream.next_in = (void*)buf;
-      zi->ci.bstream.avail_in = len;
-      err = BZ_RUN_OK;
-
-      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
-      {
-        if (zi->ci.bstream.avail_out == 0)
-        {
-          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-            err = ZIP_ERRNO;
-          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
-          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
-        }
-
-
-        if(err != BZ_RUN_OK)
-          break;
-
-        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-        {
-          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
-//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
-          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
-
-          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
-        }
-      }
-
-      if(err == BZ_RUN_OK)
-        err = ZIP_OK;
-    }
-    else
-#endif
-    {
-      zi->ci.stream.next_in = (Bytef*)buf;
-      zi->ci.stream.avail_in = len;
-
-      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
-      {
-          if (zi->ci.stream.avail_out == 0)
-          {
-              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-                  err = ZIP_ERRNO;
-              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-              zi->ci.stream.next_out = zi->ci.buffered_data;
-          }
-
-
-          if(err != ZIP_OK)
-              break;
-
-          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-          {
-              uLong uTotalOutBefore = zi->ci.stream.total_out;
-              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
-              if(uTotalOutBefore > zi->ci.stream.total_out)
-              {
-                int bBreak = 0;
-                bBreak++;
-              }
-
-              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-          }
-          else
-          {
-              uInt copy_this,i;
-              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
-                  copy_this = zi->ci.stream.avail_in;
-              else
-                  copy_this = zi->ci.stream.avail_out;
-
-              for (i = 0; i < copy_this; i++)
-                  *(((char*)zi->ci.stream.next_out)+i) =
-                      *(((const char*)zi->ci.stream.next_in)+i);
-              {
-                  zi->ci.stream.avail_in -= copy_this;
-                  zi->ci.stream.avail_out-= copy_this;
-                  zi->ci.stream.next_in+= copy_this;
-                  zi->ci.stream.next_out+= copy_this;
-                  zi->ci.stream.total_in+= copy_this;
-                  zi->ci.stream.total_out+= copy_this;
-                  zi->ci.pos_in_buffered_data += copy_this;
-              }
-          }
-      }// while(...)
-    }
-
-    return err;
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
-{
-    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
-{
-    zip64_internal* zi;
-    ZPOS64_T compressed_size;
-    uLong invalidValue = 0xffffffff;
-    short datasize = 0;
-    int err=ZIP_OK;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 0)
-        return ZIP_PARAMERROR;
-    zi->ci.stream.avail_in = 0;
-
-    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-                {
-                        while (err==ZIP_OK)
-                        {
-                                uLong uTotalOutBefore;
-                                if (zi->ci.stream.avail_out == 0)
-                                {
-                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-                                                err = ZIP_ERRNO;
-                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-                                        zi->ci.stream.next_out = zi->ci.buffered_data;
-                                }
-                                uTotalOutBefore = zi->ci.stream.total_out;
-                                err=deflate(&zi->ci.stream,  Z_FINISH);
-                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-                        }
-                }
-    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-    {
-#ifdef HAVE_BZIP2
-      err = BZ_FINISH_OK;
-      while (err==BZ_FINISH_OK)
-      {
-        uLong uTotalOutBefore;
-        if (zi->ci.bstream.avail_out == 0)
-        {
-          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-            err = ZIP_ERRNO;
-          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
-          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
-        }
-        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
-        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
-        if(err == BZ_STREAM_END)
-          err = Z_STREAM_END;
-
-        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
-      }
-
-      if(err == BZ_FINISH_OK)
-        err = ZIP_OK;
-#endif
-    }
-
-    if (err==Z_STREAM_END)
-        err=ZIP_OK; /* this is normal */
-
-    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
-                {
-        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
-            err = ZIP_ERRNO;
-                }
-
-    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-    {
-        int tmp_err = deflateEnd(&zi->ci.stream);
-        if (err == ZIP_OK)
-            err = tmp_err;
-        zi->ci.stream_initialised = 0;
-    }
-#ifdef HAVE_BZIP2
-    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-    {
-      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
-                        if (err==ZIP_OK)
-                                err = tmperr;
-                        zi->ci.stream_initialised = 0;
-    }
-#endif
-
-    if (!zi->ci.raw)
-    {
-        crc32 = (uLong)zi->ci.crc32;
-        uncompressed_size = zi->ci.totalUncompressedData;
-    }
-    compressed_size = zi->ci.totalCompressedData;
-
-#    ifndef NOCRYPT
-    compressed_size += zi->ci.crypt_header_size;
-#    endif
-
-    // update Current Item crc and sizes,
-    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
-    {
-      /*version Made by*/
-      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
-      /*version needed*/
-      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
-
-    }
-
-    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
-
-
-    if(compressed_size >= 0xffffffff)
-      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
-    else
-      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
-
-    /// set internal file attributes field
-    if (zi->ci.stream.data_type == Z_ASCII)
-        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
-
-    if(uncompressed_size >= 0xffffffff)
-      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
-    else
-      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
-
-    // Add ZIP64 extra info field for uncompressed size
-    if(uncompressed_size >= 0xffffffff)
-      datasize += 8;
-
-    // Add ZIP64 extra info field for compressed size
-    if(compressed_size >= 0xffffffff)
-      datasize += 8;
-
-    // Add ZIP64 extra info field for relative offset to local file header of current file
-    if(zi->ci.pos_local_header >= 0xffffffff)
-      datasize += 8;
-
-    if(datasize > 0)
-    {
-      char* p = NULL;
-
-      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
-      {
-        // we can not write more data to the buffer that we have room for.
-        return ZIP_BADZIPFILE;
-      }
-
-      p = zi->ci.central_header + zi->ci.size_centralheader;
-
-      // Add Extra Information Header for 'ZIP64 information'
-      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
-      p += 2;
-      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
-      p += 2;
-
-      if(uncompressed_size >= 0xffffffff)
-      {
-        zip64local_putValue_inmemory(p, uncompressed_size, 8);
-        p += 8;
-      }
-
-      if(compressed_size >= 0xffffffff)
-      {
-        zip64local_putValue_inmemory(p, compressed_size, 8);
-        p += 8;
-      }
-
-      if(zi->ci.pos_local_header >= 0xffffffff)
-      {
-        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
-        p += 8;
-      }
-
-      // Update how much extra free space we got in the memory buffer
-      // and increase the centralheader size so the new ZIP64 fields are included
-      // ( 4 below is the size of HeaderID and DataSize field )
-      zi->ci.size_centralExtraFree -= datasize + 4;
-      zi->ci.size_centralheader += datasize + 4;
-
-      // Update the extra info size field
-      zi->ci.size_centralExtra += datasize + 4;
-      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
-    }
-
-    if (err==ZIP_OK)
-        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
-
-    free(zi->ci.central_header);
-
-    if (err==ZIP_OK)
-    {
-        // Update the LocalFileHeader with the new values.
-
-        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
-
-        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err = ZIP_ERRNO;
-
-        if (err==ZIP_OK)
-            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
-        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
-        {
-          if(zi->ci.pos_zip64extrainfo > 0)
-          {
-            // Update the size in the ZIP64 extended field.
-            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
-              err = ZIP_ERRNO;
-
-            if (err==ZIP_OK) /* compressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
-
-            if (err==ZIP_OK) /* uncompressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
-          }
-          else
-              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
-        }
-        else
-        {
-          if (err==ZIP_OK) /* compressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
-          if (err==ZIP_OK) /* uncompressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-        }
-
-        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err = ZIP_ERRNO;
-    }
-
-    zi->number_entry ++;
-    zi->in_opened_file_inzip = 0;
-
-    return err;
-}
-
-extern int ZEXPORT zipCloseFileInZip (zipFile file)
-{
-    return zipCloseFileInZipRaw (file,0,0);
-}
-
-int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
-{
-  int err = ZIP_OK;
-  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
-
-  /*num disks*/
-    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
-
-  /*relative offset*/
-    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
-
-  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
-    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
-
-    return err;
-}
-
-int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
-{
-  int err = ZIP_OK;
-
-  uLong Zip64DataSize = 44;
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
-
-  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
-
-  if (err==ZIP_OK) /* version made by */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
-
-  if (err==ZIP_OK) /* version needed */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
-
-  if (err==ZIP_OK) /* number of this disk */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
-
-  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
-
-  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
-    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
-
-  if (err==ZIP_OK) /* total number of entries in the central dir */
-    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
-
-  if (err==ZIP_OK) /* size of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
-
-  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
-  {
-    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
-  }
-  return err;
-}
-int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
-{
-  int err = ZIP_OK;
-
-  /*signature*/
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
-
-  if (err==ZIP_OK) /* number of this disk */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
-  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
-  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
-  {
-    {
-      if(zi->number_entry >= 0xFFFF)
-        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
-      else
-        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-    }
-  }
-
-  if (err==ZIP_OK) /* total number of entries in the central dir */
-  {
-    if(zi->number_entry >= 0xFFFF)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-  }
-
-  if (err==ZIP_OK) /* size of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
-
-  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
-  {
-    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
-    if(pos >= 0xffffffff)
-    {
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
-    }
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
-  }
-
-   return err;
-}
-
-int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
-{
-  int err = ZIP_OK;
-  uInt size_global_comment = 0;
-
-  if(global_comment != NULL)
-    size_global_comment = (uInt)strlen(global_comment);
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
-
-  if (err == ZIP_OK && size_global_comment > 0)
-  {
-    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
-      err = ZIP_ERRNO;
-  }
-  return err;
-}
-
-extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
-{
-    zip64_internal* zi;
-    int err = 0;
-    uLong size_centraldir = 0;
-    ZPOS64_T centraldir_pos_inzip;
-    ZPOS64_T pos;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 1)
-    {
-        err = zipCloseFileInZip (file);
-    }
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-    if (global_comment==NULL)
-        global_comment = zi->globalcomment;
-#endif
-
-    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
-
-    if (err==ZIP_OK)
-    {
-        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
-        while (ldi!=NULL)
-        {
-            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
-            {
-                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
-                    err = ZIP_ERRNO;
-            }
-
-            size_centraldir += ldi->filled_in_this_block;
-            ldi = ldi->next_datablock;
-        }
-    }
-    free_linkedlist(&(zi->central_dir));
-
-    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
-    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
-    {
-      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
-      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
-
-      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
-    }
-
-    if (err==ZIP_OK)
-      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
-
-    if(err == ZIP_OK)
-      err = Write_GlobalComment(zi, global_comment);
-
-    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
-        if (err == ZIP_OK)
-            err = ZIP_ERRNO;
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-    TRYFREE(zi->globalcomment);
-#endif
-    TRYFREE(zi);
-
-    return err;
-}
-
-extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
-{
-  char* p = pData;
-  int size = 0;
-  char* pNewHeader;
-  char* pTmp;
-  short header;
-  short dataSize;
-
-  int retVal = ZIP_OK;
-
-  if(pData == NULL || *dataLen < 4)
-    return ZIP_PARAMERROR;
-
-  pNewHeader = (char*)ALLOC(*dataLen);
-  pTmp = pNewHeader;
-
-  while(p < (pData + *dataLen))
-  {
-    header = *(short*)p;
-    dataSize = *(((short*)p)+1);
-
-    if( header == sHeader ) // Header found.
-    {
-      p += dataSize + 4; // skip it. do not copy to temp buffer
-    }
-    else
-    {
-      // Extra Info block should not be removed, So copy it to the temp buffer.
-      memcpy(pTmp, p, dataSize + 4);
-      p += dataSize + 4;
-      size += dataSize + 4;
-    }
-
-  }
-
-  if(size < *dataLen)
-  {
-    // clean old extra info block.
-    memset(pData,0, *dataLen);
-
-    // copy the new extra info block over the old
-    if(size > 0)
-      memcpy(pData, pNewHeader, size);
-
-    // set the new extra info size
-    *dataLen = size;
-
-    retVal = ZIP_OK;
-  }
-  else
-    retVal = ZIP_ERRNO;
-
-  TRYFREE(pNewHeader);
-
-  return retVal;
-}

+ 0 - 367
library/third_party/minizip/zip.h

@@ -1,367 +0,0 @@
-/* zip.h -- IO on .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         ---------------------------------------------------------------------------
-
-   Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-        ---------------------------------------------------------------------------
-
-        Changes
-
-        See header of zip.h
-
-*/
-
-/* Pragma added by libxlsxwriter project to avoid warnings with -pedantic -ansi. */
-#ifndef _WIN32
-#pragma GCC system_header
-#endif
-
-#ifndef _zip12_H
-#define _zip12_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* #define HAVE_BZIP2 */
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#ifdef HAVE_BZIP2
-#include "bzlib.h"
-#endif
-
-#define Z_BZIP2ED 12
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK                          (0)
-#define ZIP_EOF                         (0)
-#define ZIP_ERRNO                       (Z_ERRNO)
-#define ZIP_PARAMERROR                  (-102)
-#define ZIP_BADZIPFILE                  (-103)
-#define ZIP_INTERNALERROR               (-104)
-
-#ifndef DEF_MEM_LEVEL
-#  if MAX_MEM_LEVEL >= 8
-#    define DEF_MEM_LEVEL 8
-#  else
-#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#  endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
-    tm_zip      tmz_date;       /* date in understandable format           */
-    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
-/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
-
-    uLong       internal_fa;    /* internal file attributes        2 bytes */
-    uLong       external_fa;    /* external file attributes        4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE        (0)
-#define APPEND_STATUS_CREATEAFTER   (1)
-#define APPEND_STATUS_ADDINZIP      (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
-/*
-  Create a zipfile.
-     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
-       an Unix computer "zlib/zlib113.zip".
-     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
-       will be created at the end of the file.
-         (useful if the file contain a self extractor code)
-     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
-       add files in existing zip (be sure you don't add file that doesn't exist)
-     If the zipfile cannot be opened, the return value is NULL.
-     Else, the return value is a zipFile Handle, usable with other function
-       of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
-   If you want delete file into a zipfile, you must open a zipfile, and create another
-   Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc_def* pzlib_filefunc_def));
-
-extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc64_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level));
-
-extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level,
-                       int zip64));
-
-/*
-  Open a file in the ZIP for writing.
-  filename : the filename in zip (if NULL, '-' without quote will be used
-  *zipfi contain supplemental information
-  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
-    contains the extrafield data the the local header
-  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
-    contains the extrafield data the the local header
-  if comment != NULL, comment contain the comment string
-  method contain the compression method (0 for store, Z_DEFLATED for deflate)
-  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
-                    this MUST be '1' if the uncompressed size is >= 0xffffffff.
-
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw));
-
-
-extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int zip64));
-/*
-  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting));
-
-extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            int zip64
-                                            ));
-
-/*
-  Same than zipOpenNewFileInZip2, except
-    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
-    password : crypting password (NULL for no crypting)
-    crcForCrypting : crc of file to compress (needed for crypting)
- */
-
-extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase
-                                            ));
-
-
-extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase,
-                                            int zip64
-                                            ));
-/*
-  Same than zipOpenNewFileInZip4, except
-    versionMadeBy : value for Version made by field
-    flag : value for flag field (compression level info will be added)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
-                       const void* buf,
-                       unsigned len));
-/*
-  Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
-  Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
-                                            uLong uncompressed_size,
-                                            uLong crc32));
-
-extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
-                                            ZPOS64_T uncompressed_size,
-                                            uLong crc32));
-
-/*
-  Close the current file in the zipfile, for file opened with
-    parameter raw=1 in zipOpenNewFileInZip2
-  uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
-                const char* global_comment));
-/*
-  Close the zipfile
-*/
-
-
-extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
-/*
-  zipRemoveExtraInfoBlock -  Added by Mathias Svensson
-
-  Remove extra information block from a extra information data for the local file header or central directory header
-
-  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
-
-  0x0001 is the signature header for the ZIP64 extra information blocks
-
-  usage.
-                        Remove ZIP64 Extra information from a central director extra field data
-              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
-
-                        Remove ZIP64 Extra information from a Local File Header extra field data
-        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip64_H */

+ 0 - 342
library/third_party/tmpfileplus/tmpfileplus.c

@@ -1,342 +0,0 @@
-/* $Id: tmpfileplus.c $ */
-/*
- * $Date: 2016-06-01 03:31Z $
- * $Revision: 2.0.0 $
- * $Author: dai $
- */
-
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
- * <http://www.di-mgt.com.au/contact/>.
- */
-
-
-/*
-* NAME
-*        tmpfileplus - create a unique temporary file
-*
-* SYNOPSIS
-*        FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep)
-*
-* DESCRIPTION
-*        The tmpfileplus() function opens a unique temporary file in binary
-*        read/write (w+b) mode. The file is opened with the O_EXCL flag,
-*        guaranteeing that the caller is the only user. The filename will consist
-*        of the string given by `prefix` followed by 10 random characters. If
-*        `prefix` is NULL, then the string "tmp." will be used instead. The file
-*        will be created in an appropriate directory chosen by the first
-*        successful attempt in the following sequence:
-*
-*        a) The directory given by the `dir` argument (so the caller can specify
-*        a secure directory to take precedence).
-*
-*        b) The directory name in the environment variables:
-*
-*          (i)   "TMP" [Windows only]
-*          (ii)  "TEMP" [Windows only]
-*          (iii) "TMPDIR" [Unix only]
-*
-*        c) `P_tmpdir` as defined in <stdio.h> [Unix only] (in Windows, this is
-*        usually "\", which is no good).
-*
-*        d) The current working directory.
-*
-*        If a file cannot be created in any of the above directories, then the
-*        function fails and NULL is returned.
-*
-*        If the argument `pathname` is not a null pointer, then it will point to
-*        the full pathname of the file. The pathname is allocated using `malloc`
-*        and therefore should be freed by `free`.
-*
-*        If `keep` is nonzero and `pathname` is not a null pointer, then the file
-*        will be kept after it is closed. Otherwise the file will be
-*        automatically deleted when it is closed or the program terminates.
-*
-*
-* RETURN VALUE
-*        The tmpfileplus() function returns a pointer to the open file stream,
-*        or NULL if a unique file cannot be opened.
-*
-*
-* ERRORS
-*        ENOMEM Not enough memory to allocate filename.
-*
-*/
-
-/* ADDED IN v2.0 */
-
-/*
-* NAME
-*        tmpfileplus_f - create a unique temporary file with filename stored in a fixed-length buffer
-*
-* SYNOPSIS
-*        FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
-*
-* DESCRIPTION
-*        Same as tmpfileplus() except receives filename in a fixed-length buffer. No allocated memory to free.
-
-* ERRORS
-*        E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
-
-*/
-
-#include "tmpfileplus.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-/* Non-ANSI include files that seem to work in both MSVC and Linux */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
-#ifdef _WIN32
-/* MSVC nags to enforce ISO C++ conformant function names with leading "_",
- * so we define our own function names to avoid whingeing compilers...
- */
-#define OPEN_ _open
-#define FDOPEN_ _fdopen
-#else
-#define OPEN_ open
-#define FDOPEN_ fdopen
-#endif
-
-
-/* DEBUGGING STUFF */
-#if defined(_DEBUG) && defined(SHOW_DPRINTF)
-#define DPRINTF1(s, a1) printf(s, a1)
-#else
-#define DPRINTF1(s, a1)
-#endif
-
-
-#ifdef _WIN32
-#define FILE_SEPARATOR "\\"
-#else
-#define FILE_SEPARATOR "/"
-#endif
-
-#define RANDCHARS	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
-#define NRANDCHARS	(sizeof(RANDCHARS) - 1)
-
-/** Replace each byte in string s with a random character from TEMPCHARS */
-static char *set_randpart(char *s)
-{
-	size_t i;
-	unsigned int r;
-	static unsigned int seed;	/* NB static */
-
-	if (seed == 0)
-	{	/* First time set our seed using current time and clock */
-		seed = ((unsigned)time(NULL)<<8) ^ (unsigned)clock();
-	}
-	srand(seed++);
-	for (i = 0; i < strlen(s); i++)
-	{
-		r = rand() % NRANDCHARS;
-		s[i] = (RANDCHARS)[r];
-	}
-	return s;
-}
-
-/** Return 1 if path is a valid directory otherwise 0 */
-static int is_valid_dir(const char *path)
-{
-	struct stat st;
-	if ((stat(path, &st) == 0) && (st.st_mode & S_IFDIR))
-		return 1;
-
-	return 0;
-}
-
-/** Call getenv and save a copy in buf */
-static char *getenv_save(const char *varname, char *buf, size_t bufsize)
-{
-	char *ptr = getenv(varname);
-	buf[0] = '\0';
-	if (ptr)
-	{
-		strncpy(buf, ptr, bufsize);
-		buf[bufsize-1] = '\0';
-		return buf;
-	}
-	return NULL;
-}
-
-/**
- * Try and create a randomly-named file in directory `tmpdir`.
- * If successful, allocate memory and set `tmpname_ptr` to full filepath, and return file pointer;
- * otherwise return NULL.
- * If `keep` is zero then create the file as temporary and it should not exist once closed.
- */
-static FILE *mktempfile_internal(const char *tmpdir, const char *pfx, char **tmpname_ptr, int keep)
-/* PRE:
- * pfx is not NULL and points to a valid null-terminated string
- * tmpname_ptr is not NULL.
- */
-{
-	FILE *fp;
-	int fd;
-	char randpart[] = "1234567890";
-	size_t lentempname;
-	int i;
-	char *tmpname = NULL;
-	int oflag, pmode;
-
-/* In Windows, we use the _O_TEMPORARY flag with `open` to ensure the file is deleted when closed.
- * In Unix, we use the unlink function after opening the file. (This does not work in Windows,
- * which does not allow an open file to be unlinked.)
- */
-#ifdef _WIN32
-	/* MSVC flags */
-	oflag =  _O_BINARY|_O_CREAT|_O_EXCL|_O_RDWR;
-	if (!keep)
-		oflag |= _O_TEMPORARY;
-	pmode = _S_IREAD | _S_IWRITE;
-#else
-	/* Standard POSIX flags */
-	oflag = O_CREAT|O_EXCL|O_RDWR;
-	pmode = S_IRUSR|S_IWUSR;
-#endif
-
-	if (!tmpdir || !is_valid_dir(tmpdir)) {
-		errno = ENOENT;
-		return NULL;
-	}
-
-	lentempname = strlen(tmpdir) + strlen(FILE_SEPARATOR) + strlen(pfx) + strlen(randpart);
-	DPRINTF1("lentempname=%d\n", lentempname);
-	tmpname = malloc(lentempname + 1);
-	if (!tmpname)
-	{
-		errno = ENOMEM;
-		return NULL;
-	}
-	/* If we don't manage to create a file after 10 goes, there is something wrong... */
-	for (i = 0; i < 10; i++)
-	{
-		sprintf(tmpname, "%s%s%s%s", tmpdir, FILE_SEPARATOR, pfx, set_randpart(randpart));
-		DPRINTF1("[%s]\n", tmpname);
-		fd = OPEN_(tmpname, oflag, pmode);
-		if (fd != -1) break;
-	}
-	DPRINTF1("strlen(tmpname)=%d\n", strlen(tmpname));
-	if (fd != -1)
-	{	/* Success, so return user a proper ANSI C file pointer */
-		fp = FDOPEN_(fd, "w+b");
-		errno = 0;
-
-#ifndef _WIN32
-		/* [Unix only] And make sure the file will be deleted once closed */
-		if (!keep) unlink(tmpname);
-#endif
-
-	}
-	else
-	{	/* We failed */
-		fp = NULL;
-	}
-	if (!fp)
-	{
-		free(tmpname);
-		tmpname = NULL;
-	}
-
-	*tmpname_ptr = tmpname;
-	return fp;
-}
-
-/**********************/
-/* EXPORTED FUNCTIONS */
-/**********************/
-
-FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep)
-{
-	FILE *fp = NULL;
-	char *tmpname = NULL;
-	char *tmpdir = NULL;
-	const char *pfx = (prefix ? prefix : "tmp.");
-	char *tempdirs[12] = { 0 };
-#ifdef _WIN32
-	char env1[FILENAME_MAX+1] = { 0 };
-	char env2[FILENAME_MAX+1] = { 0 };
-#else
-	char env3[FILENAME_MAX+1] = { 0 };
-#endif
-	int ntempdirs = 0;
-	int i;
-
-	/* Set up a list of temp directories we will try in order */
-	i = 0;
-	tempdirs[i++] = (char *)dir;
-#ifdef _WIN32
-	tempdirs[i++] = getenv_save("TMP", env1, sizeof(env1));
-	tempdirs[i++] = getenv_save("TEMP", env2, sizeof(env2));
-#else
-	tempdirs[i++] = getenv_save("TMPDIR", env3, sizeof(env3));
-	tempdirs[i++] = P_tmpdir;
-#endif
-	tempdirs[i++] = ".";
-	ntempdirs = i;
-
-	errno = 0;
-
-	/* Work through list we set up before, and break once we are successful */
-	for (i = 0; i < ntempdirs; i++)
-	{
-		tmpdir = tempdirs[i];
-		DPRINTF1("Trying tmpdir=[%s]\n", tmpdir);
-		fp = mktempfile_internal(tmpdir, pfx, &tmpname, keep);
-		if (fp) break;
-	}
-	/* If we succeeded and the user passed a pointer, set it to the alloc'd pathname: the user must free this */
-	if (fp && pathname)
-		*pathname = tmpname;
-	else	/* Otherwise, free the alloc'd memory */
-		free(tmpname);
-
-	return fp;
-}
-
-/* Same as tmpfileplus() but with fixed length buffer for output filename and no memory allocation */
-FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep)
-{
-	char *tmpbuf = NULL;
-	FILE *fp;
-
-	/* If no buffer provided, do the normal way */
-	if (!pathnamebuf || (int)pathsize <= 0) {
-		return tmpfileplus(dir, prefix, NULL, keep);
-	}
-	/* Call with a temporary buffer */
-	fp = tmpfileplus(dir, prefix, &tmpbuf, keep);
-	if (fp && strlen(tmpbuf) > pathsize - 1) {
-		/* Succeeded but not enough room in output buffer, so clean up and return an error */
-		pathnamebuf[0] = 0;
-		fclose(fp);
-		if (keep) remove(tmpbuf);
-		free(tmpbuf);
-		errno = E2BIG;
-		return NULL;
-	}
-	/* Copy name into buffer */
-	strcpy(pathnamebuf, tmpbuf);
-	free(tmpbuf);
-
-	return fp;
-}
-
-

+ 0 - 53
library/third_party/tmpfileplus/tmpfileplus.h

@@ -1,53 +0,0 @@
-/* $Id: tmpfileplus.h $ */
-/*
- * $Date: 2016-06-01 03:31Z $
- * $Revision: 2.0.0 $
- * $Author: dai $
- */
-
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
- * <http://www.di-mgt.com.au/contact/>.
- */
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifndef TMPFILEPLUS_H_
-#define TMPFILEPLUS_H_
-
-#include <stdio.h>
-
-/** Create a unique temporary file.
-@param dir (optional) directory to create file. If NULL use default TMP directory.
-@param prefix (optional) prefix for file name. If NULL use "tmp.".
-@param pathname (optional) pointer to a buffer to receive the temp filename. 
-	Allocated using `malloc()`; user to free. Ignored if NULL.
-@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 
-	Otherwise file is automatically deleted when closed.
-@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
-@exception ENOMEM Not enough memory to allocate filename.
-*/
-FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
-
-
-/** Create a unique temporary file with filename stored in a fixed-length buffer.
-@param dir (optional) directory to create file. If NULL use default directory.
-@param prefix (optional) prefix for file name. If NULL use "tmp.".
-@param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL.
-@param pathsize Size of buffer to receive filename and its terminating null character.
-@param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing.
-	Otherwise file is automatically deleted when closed.
-@return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
-@exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
-*/
-FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
-
-#define TMPFILE_KEEP 1
-
-#endif /* end TMPFILEPLUS_H_ */